# codebook 25頁 ## 目錄 * 常用函式 * LIS * 背包 * 線段樹 lazy tag * priorty queue 自訂排序 * matrix乘法 * Floyd-Warshall * dijkstra * treap 持久化 ## iomanip IO manipulation:控制輸出格式 setbase() setbase(8) setbase(10) setbase(16) 輸出的進位制 setprecision() 輸出的位數 搭配fixed輸出小數點後的位數 setw()設定列出寬度 setfill()寬度不足填的字元' ' '0' ## 常用函式 #include<bits/stdc++.h> fill(a,a+n,0);fill(v.begin(),v.end(),0);填入0 accumulate(v.begin,v.end(),0); adjacent_difference(v.begin(),v.end(),t.begin()); partial_sum(v.begin(),v.end(),t.begin());前綴和 max_element(v.begin(),v.end())回傳最大元素的位子 min_element(v.begin(),v.end())回傳最小元素的位子 auto it = binary_search(v.begin(), v.end(), val); auto it = under_bound(v.begin(), v.end(), val); 回傳<val的位子=lower_bound-1 auto it = lower_bound(v.begin(), v.end(), val); 回傳大於等於val的位子 auto it = upper_bound(v.begin(), v.end(), val); 回傳>val的位子 # LIS ```cpp= vector<int> LIS(const vector<int>& s) { vector<int> v; v.push_back(s[0]); for (int i{1}; i < s.size(); ++i) if (s[i] > v.back()) v.push_back(s[i]); else *lower_bound(v.begin(), v.end(), s[i]) = s[i]; return v; } ``` # 背包 ```cpp= int n,m;//n item weigh limit int v[n],w[n]; for(int i=0;i<n;++i) { cin>>v[i]>>w[i]; } int dp[m+1]; fill(dp,dp+m+1,0); for(int i=0;i<n;++i) { for(int j=m;j>=v[i];--j) { dp[j]=max(dp[j],dp[j-w[i]]+v[i]); } } cout<<dp[w]; ``` ## 線段樹 lazy tag ```cpp= class segment{ class node{ public: long long val = 0; long long lazy=0; long long leaf=1ll; }; vector<node> tree; int n; public: segment(vector<long long>& a){ n=a.size(); tree.resize(n<<1); for(int i=0; i<n; ++i) tree[i+n].val=a[i]; for(int i=n-1; i>0; --i) { tree[i].val=tree[i<<1].val+tree[i<<1|1].val; tree[i].leaf=tree[i<<1].leaf+tree[i<<1|1].leaf; } } void apply(int now,long long& inc) { tree[now].lazy += inc; tree[now].val += inc*tree[now].leaf; } void push(int now)//push down { if(now>=n) return; if(tree[now].lazy) { apply(now<<1,tree[now].lazy); apply(now<<1|1,tree[now].lazy); tree[now].lazy = 0; } } void pull(int& now)//pull up { for (int i_Op = now; i_Op;i_Op>>=1) { push(i_Op>>1); tree[i_Op>>1].val=tree[i_Op].val+tree[i_Op^1].val; } } void modify(int l,int r,long long& inc) { for (int i_Op = l + n, i_Ed = r + n; i_Op < i_Ed;i_Op>>=1,i_Ed>>=1) { if(i_Op&1) { apply(i_Op,inc); pull(i_Op); i_Op++; } if(i_Ed&1) { --i_Ed; apply(i_Ed,inc); pull(i_Ed); } } } void pushPath(int& p) { for (int h = __lg(n); h > 0; h--) { int i = p >> h; push(i); } } long long query(int l, int r) { // 推送懶人標記 long long res = 0; for (l += n, r += n; l < r; l >>= 1, r >>= 1) { if (l & 1) { pushPath(l); res += tree[l].val; l++; } if (r & 1) { r--; pushPath(r); res += tree[r].val; } } return res; } }; ``` ## priorty queue 自訂排序 ```cpp= class Class { public: int a, b, c; Class(int _a, int _b, int _c) : a(_a), b(_b), c(_c) {} }; int main() { auto comp = [](const Class& lhs, const Class& rhs) { if (lhs.b != rhs.b) return lhs.b > rhs.b; // 按b的升序排序 if (lhs.a != rhs.a) return lhs.a > rhs.a; // 如果b相同,則按a的升序排序 return lhs.c > rhs.c; // 如果a和b都相同,則按c的升序排序 }; priority_queue<Class, vector<Class>, decltype(comp)> pq(comp); ``` ## matrix ```cpp= vector<vector<int>> operator*(const vector<std::vector<int>>& A, const vector<vector<int>>& B) { int m = A.size(); int n = A[0].size(); int p = B[0].size(); vector<vector<int>> C(m,vector<int>(p, 0)); for (int i = 0; i < m; ++i) { for (int j = 0; j < p; ++j) { for (int k = 0; k < n; ++k) { C[i][j] += A[i][k] * B[k][j]; } } } return C; } ``` ## dijkstra ```cpp= vector<long long> dijkstra(vector<vector<pair<int,long long>>>& v) vector<long long> dist(n,(1ll<<60)); dist[0] = 0; priority_queue < tuple<long long, int, int>, vector<tuple<long long, int, int>>, greater<tuple<long long, int, int>>> pq; pq.push({0, 0, 0}); while(!pq.empty()) { auto [d,now,dis] = pq.top(); pq.pop(); if (d > dist[now]) continue; for (auto& i:v[now]){ if (dist[i.first] > d + i.second) { dist[i.first] = d + i.second; pq.push({dist[i.first], i.first, dis}); } } } return v; } ``` ## Floyd-Warshall ```cpp= vector<vector<long long>> dis(n,vector<long long>(n,(1ll<<60))); for (int i=0,u,v,w; i<m; i++) cin >> u >> v >> w, dis[u][v] = w; for (int k=0; k<n; k++) for (int i=0; i<n; i++) for (int j=0; j<n; j++) dis[i][j] = min(dis[i][j],dis[i][k]+dis[k][j]); ``` ## treap ```cpp= class node{ public: long long index, pri; long long val, sum; shared_ptr<node> l, r; node(long long k, long long v) : index(k), pri(rand()), val(v), sum(v), l(nullptr), r(nullptr){ } node(shared_ptr<node> t): index(t->index), pri(t->pri), val(t->val), sum(t->sum), l(t->l), r(t->r){ } }; class Treap { public: vector<shared_ptr<node>> root; int n=0; Treap() { root.push_back(nullptr); } void insert(long long v) { shared_ptr<node> node_tmp(new node(n, v)); root[0]=merge(root[0], node_tmp); ++n; } long long get_Sum(shared_ptr<node>t) { return t ? t->sum : 0ll; } void update(int v,int k,int u) { root[v]=update(root[v],k,u); } shared_ptr<node> update(shared_ptr<node> t,int k,long long u) { if(!t) { return nullptr; } shared_ptr<node> new_Node( new node(t)); if(t->index<k) { new_Node->r=update(t->r,k,u); } else if(t->index>k) { new_Node->l=update(t->l,k,u); } else //if(t->index==k) { //shared_ptr<node> new_Node= new node(t); new_Node->val = u; } pull(new_Node); return new_Node; } long long query(int v,int l,int r) { shared_ptr<node> a,b,c; split_By_Index(root[v], l - 1, a, b); split_By_Index(b, r, b, c); long long ans = get_Sum(b); root[v] = merge(a, merge(b, c)); return ans; } void copy_Back(int k) { root.push_back(shared_ptr<node>(new node(root[k]))); } private: void pull(shared_ptr<node> t) { t->sum = t->val + get_Sum(t->l) + get_Sum(t->r); } private: shared_ptr<node> merge(shared_ptr<node> a,shared_ptr<node> b) { if(!a || !b) return a ? a : b; if(a->pri > b->pri) { a->r=merge(a->r,b); pull(a); return a; } else { b->l=merge(a,b->l); pull(b); return b; } } private: void split_By_Index(shared_ptr<node>t,int k,shared_ptr<node>&a,shared_ptr<node>&b) { if(!t) { a=b= nullptr; return; } if(t->index<=k) { a = t; split_By_Index(t->r,k,a->r,b); pull(a); } else { b = t; split_By_Index(t->l, k, a, b->l); pull(b); } } }; ```