├── Sieve.cpp ├── Floor sum trick.cpp ├── factorials.cpp ├── DSU.cpp ├── Template.cpp ├── Matrix.cpp ├── XorBasis.cpp ├── RangeUpdate.cpp ├── SegmentTree.cpp ├── LiChaoTree.cpp ├── LazySegmentTree.cpp └── persistent segment tree /Sieve.cpp: -------------------------------------------------------------------------------- 1 | vector primes; 2 | void sieve(const int n){ 3 | vector prime(n+1, 1); 4 | for(int i=2;i*i<=n;i++){ 5 | if(prime[i]){ 6 | primes.pb(i); 7 | for(int j=2*i;j<=n;j+=i){ 8 | prime[j]=0; 9 | } 10 | } 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /Floor sum trick.cpp: -------------------------------------------------------------------------------- 1 | ll floorsum(ll n,ll l, ll r){ 2 | if(l == r){ 3 | return n/l; 4 | } 5 | if(r - l == 1){ 6 | return n/l + n/r; 7 | } 8 | if(n/l == n/r){ 9 | return (r - l + 1) * (n/l); 10 | } 11 | ll mid = (l + r)/2; 12 | return floorsum(l, mid) + floorsum(mid + 1, r); 13 | } 14 | -------------------------------------------------------------------------------- /factorials.cpp: -------------------------------------------------------------------------------- 1 | ll modpower(ll base, ll power, ll mod=p){ 2 | ll ans =1; 3 | base%=mod; 4 | while(power){ 5 | if(power&1){ 6 | ans*=base; 7 | ans%=mod; 8 | } 9 | base*=base; 10 | base%=mod; 11 | power>>=1; 12 | } 13 | return ans; 14 | } 15 | vector fact; 16 | vector invfact; 17 | void computefactorial(int n){ 18 | ++n; 19 | fact.resize(n); 20 | invfact.resize(n); 21 | fact[0]=1; 22 | for(int i=1;i=0;i--){ 28 | invfact[i]=(i+1)*invfact[i+1]; 29 | invfact[i]%=p; 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /DSU.cpp: -------------------------------------------------------------------------------- 1 | struct DSU{ 2 | vector parent; 3 | vector sizof; 4 | int n; 5 | DSU(int N){ 6 | n=N; 7 | parent.resize(n); 8 | sizof.resize(n); 9 | for(int i=0;i 2 | using namespace std; 3 | using ll = long long int; 4 | template 5 | ostream& operator+(ostream& out, const vector &vec){ 6 | for(const auto &x : vec){ 7 | out< 13 | ostream& operator*(ostream& out, const vector &vec){ 14 | for(const auto &x : vec){ 15 | out+x; 16 | } 17 | return out; 18 | } 19 | template 20 | istream& operator>>(istream& in, vector &vec){ 21 | for(auto &x : vec){ 22 | in>>x; 23 | } 24 | return in; 25 | } 26 | void solve(int test_case){ 27 | 28 | } 29 | int main() { 30 | ios_base::sync_with_stdio(false); 31 | cin.tie(NULL); 32 | int t = 1; 33 | cin>>t; 34 | for(int i=1;i<=t;i++){ 35 | solve(i); 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /Matrix.cpp: -------------------------------------------------------------------------------- 1 | struct matrix{ 2 | vector> mat; 3 | matrix(int n, int m){ 4 | mat.resize(n,vector(m)); 5 | } 6 | matrix operator*(matrix a){ 7 | matrix ans(this->mat.size(),a.mat[0].size()); 8 | for(int i=0;imat.size();i++){ 9 | for(int j=0;jmat[i][k]*a.mat[k][j]; 12 | ans.mat[i][j]%=p; 13 | } 14 | } 15 | } 16 | return ans; 17 | } 18 | }; 19 | matrix matpower(matrix base,ll power){ 20 | matrix ans(base.mat.size(),base.mat.size()); 21 | for(int i=0;i>=1; 30 | } 31 | return ans; 32 | } 33 | -------------------------------------------------------------------------------- /XorBasis.cpp: -------------------------------------------------------------------------------- 1 | struct XorBasis{ 2 | private: 3 | vector basis; 4 | int lg; 5 | int sz = 0; 6 | 7 | public: 8 | XorBasis(int lg) : lg(lg){ 9 | basis.resize(lg); 10 | } 11 | void add(ll x){ 12 | if(x >= (1ll<::iterator begin(){ 36 | return basis.begin(); 37 | } 38 | const vector::iterator end(){ 39 | return basis.end(); 40 | } 41 | }; 42 | -------------------------------------------------------------------------------- /RangeUpdate.cpp: -------------------------------------------------------------------------------- 1 | template 2 | struct RangeUpdate{ //requires commutativity and associativity 3 | int n; 4 | vector segtree; 5 | function join; 6 | T base; 7 | RangeUpdate(int n, function join, T base) : n(n), join(join), base(base){ 8 | segtree.resize(n<<1, base); 9 | } 10 | RangeUpdate(vector &seq, function join, T base) : n(seq.size()), join(join), base(base){ 11 | segtree.resize(n<<1, base); 12 | for(int i=0;i>=1; 20 | while(pos){ 21 | ans = join(ans, segtree[pos]); 22 | pos>>=1; 23 | } 24 | return ans; 25 | } 26 | void update(int l,int r,T val){ 27 | l+=n; 28 | r+=n+1; 29 | while(l < r){ 30 | if(l&1){ 31 | segtree[l] = join(segtree[l], val); 32 | ++l; 33 | } 34 | if(r&1){ 35 | --r; 36 | segtree[r] = join(segtree[r], val); 37 | } 38 | l>>=1; 39 | r>>=1; 40 | } 41 | } 42 | }; 43 | -------------------------------------------------------------------------------- /SegmentTree.cpp: -------------------------------------------------------------------------------- 1 | template 2 | struct segment_tree { 3 | int n; 4 | vector segtree; 5 | function join; 6 | T base = T(); 7 | segment_tree(int n, function join, T base = T()) : n(n), join(join), base(base){ 8 | segtree.resize(n << 1, base); 9 | } 10 | void build() { 11 | for (int i = n - 1; i > 0; --i) { 12 | segtree[i] = join(segtree[(i << 1)], segtree[(i << 1) | 1]); 13 | } 14 | } 15 | segment_tree(vector seq, function join, T base = T()) : n(seq.size()), join(join), base(base){ 16 | segtree.resize(n << 1, base); 17 | for (int i = 0; i < n; i++) { 18 | segtree[n + i] = seq[i]; 19 | } 20 | build(); 21 | } 22 | void calc(int pos){ 23 | pos >>= 1; 24 | while (pos) { 25 | segtree[pos] = join(segtree[pos << 1], segtree[(pos << 1) | 1]); 26 | pos >>= 1; 27 | } 28 | } 29 | void set(int pos, T val){ 30 | pos+=n; 31 | segtree[pos] = val; 32 | calc(pos); 33 | } 34 | void increment(int pos, T val){ 35 | pos+=n; 36 | segtree[pos] = join(segtree[pos], val); 37 | calc(pos); 38 | } 39 | T query(int l, int r) { 40 | T ansl = base; 41 | T ansr = base; 42 | l += n; 43 | r += n + 1; 44 | while (l < r) { 45 | if (l & 1) { 46 | ansl = join(ansl, segtree[l++]); 47 | } 48 | if (r & 1) { 49 | ansr = join(segtree[--r], ansr); 50 | } 51 | l >>= 1; 52 | r >>= 1; 53 | } 54 | return join(ansl, ansr); 55 | } 56 | }; 57 | -------------------------------------------------------------------------------- /LiChaoTree.cpp: -------------------------------------------------------------------------------- 1 | template 2 | struct LiChaoTree{ 3 | struct Line{ 4 | ll m,c; 5 | Line(){} 6 | Line(ll m,ll c) : m(m), c(c) {} 7 | ll evaluate(ll x){ 8 | return m*x + c; 9 | } 10 | }; 11 | struct Node{ 12 | Line top; 13 | int left=-1, right=-1; 14 | Node() {} 15 | Node(ll m, ll c) : top(Line(m,c)) {} 16 | Node (Line curr) : top(curr) {} 17 | ll evaluate(ll x){ 18 | return top.evaluate(x); 19 | } 20 | }; 21 | vector Tree; 22 | const ll INF = 1e18; 23 | LiChaoTree(){ 24 | Tree.emplace_back(0,INF); 25 | } 26 | void addline(ll m,ll c){ 27 | addline(Line(m,c),0,MAXA+1,0); 28 | } 29 | void addline(Line toadd,ll l,ll r,int idx){ 30 | ll mid = (l+r)/2; 31 | Line& top = Tree[idx].top; 32 | if(top.evaluate(mid) > toadd.evaluate(mid)){ 33 | swap(top, toadd); 34 | } 35 | if(r-l <= 1) return; 36 | if(top.evaluate(l) > toadd.evaluate(l)){ 37 | if(Tree[idx].left == -1){ 38 | Tree[idx].left = Tree.size(); 39 | Tree.emplace_back(top); 40 | } 41 | addline(toadd,l,mid,Tree[idx].left); 42 | } 43 | else{ 44 | if(Tree[idx].right == -1){ 45 | Tree[idx].right = Tree.size(); 46 | Tree.emplace_back(top); 47 | } 48 | addline(toadd,mid,r,Tree[idx].right); 49 | } 50 | } 51 | ll query(ll x){ 52 | return min(Tree[0].evaluate(x), query(x,0,MAXA+1,0));// * (maximum ? 1 : -1); 53 | } 54 | ll query(ll x,ll l,ll r,int idx){ 55 | if(idx==-1) return INF; 56 | if(x=r) return Tree[idx].evaluate(x); 57 | if(r-l <= 1) return Tree[idx].evaluate(x); 58 | ll mid = (l+r)/2; 59 | return min({Tree[idx].evaluate(x), query(x,l,mid,Tree[idx].left), query(x,mid,r,Tree[idx].right)}); 60 | } 61 | }; 62 | -------------------------------------------------------------------------------- /LazySegmentTree.cpp: -------------------------------------------------------------------------------- 1 | template 2 | struct lazy_segment_tree{ 3 | int n; 4 | int H; 5 | T base; 6 | vector segtree; 7 | vector lazytree; 8 | vector isempty; 9 | function join; 10 | function assign; 11 | function lazyassign; 12 | 13 | lazy_segment_tree(vector &seq, 14 | function join, 15 | function assign, 16 | function lazyassign, 17 | T base) : join(join), assign(assign), lazyassign(lazyassign), base(base){ 18 | n = seq.size(); 19 | H = 32 - __builtin_clz(n); 20 | segtree.resize(2*n); 21 | lazytree.resize(n); 22 | isempty.resize(n,1); 23 | for(int i=0;i=1;i--){ 27 | segtree[i]=join(segtree[(i<<1)], segtree[(i<<1)|1]); 28 | } 29 | } 30 | void calc(int pos, int h){ 31 | segtree[pos]=join(segtree[(pos<<1)],segtree[(pos<<1)|1]); 32 | if(!isempty[pos]){ 33 | segtree[pos]=assign(h,lazytree[pos],segtree[pos]); 34 | } 35 | } 36 | void apply(int pos, U value, int h){ 37 | segtree[pos]=assign(h, value, segtree[pos]); 38 | if(pos1){ 52 | h++; 53 | pos>>=1; 54 | calc(pos, h); 55 | } 56 | } 57 | void push(int pos){ 58 | int h=H; 59 | for(pos+=n;h;--h){ 60 | int x=(pos>>h); 61 | if(!isempty[x]){ 62 | apply((x<<1), lazytree[x], h-1); 63 | apply((x<<1)|1, lazytree[x], h-1); 64 | isempty[x]=1; 65 | } 66 | } 67 | } 68 | void updaterange(int l, int r, U value){ 69 | push(l); 70 | push(r); 71 | int k=0; 72 | int l0=l, r0=r; 73 | for(l+=n, r+=n+1;l>=1, r>>=1, k++){ 74 | if(l&1){ 75 | apply(l++, value, k); 76 | } 77 | if(r&1){ 78 | apply(--r, value,k); 79 | } 80 | } 81 | updatenode(l0); 82 | updatenode(r0); 83 | } 84 | T query(int l, int r){ 85 | push(l); 86 | push(r); 87 | T ansl=base; 88 | T ansr=base; 89 | for(l+=n,r+=n+1;l>=1,r>>=1){ 90 | if(l&1){ 91 | ansl=join(ansl, segtree[l++]); 92 | } 93 | if(r&1){ 94 | ansr=join(segtree[--r], ansr); 95 | } 96 | } 97 | return join(ansl,ansr); 98 | } 99 | }; 100 | -------------------------------------------------------------------------------- /persistent segment tree: -------------------------------------------------------------------------------- 1 | template 2 | struct persistent_segment_tree{ 3 | struct node{ 4 | T data; 5 | int l, r; 6 | }; 7 | int n; 8 | vector nodes; 9 | vector roots; 10 | F op; 11 | T e; 12 | persistent_segment_tree(int _n, F _op, T _e) : n(_n), op(_op), e(_e){ 13 | roots.push_back(_build(0, n, [&](int index){ 14 | return e; 15 | })); 16 | } 17 | template 18 | persistent_segment_tree(vector &a, F _op, T _e) : n(a.size()), op(_op), e(_e){ 19 | roots.push_back(_build(0, n, [&](int index){ 20 | return T(a[index]); 21 | })); 22 | } 23 | T query(int l, int r, int t){ 24 | _ql = l; _qr = r + 1; 25 | return _query(roots[t], 0, n); 26 | } 27 | void set(int index, T val, int root_id = -1){ 28 | _index = index; 29 | if(root_id == -1) root_id += roots.size(); 30 | assert(roots[root_id] != -1); 31 | roots.push_back(_update(roots[root_id], 0, n, [&](T &x){ 32 | x = val; 33 | })); 34 | } 35 | void increment(int index, T val, int root_id = -1){ 36 | _index = index; 37 | assert(0 <= _index && _index < n); 38 | if(root_id == -1) root_id += roots.size(); 39 | assert(roots[root_id] != -1); 40 | roots.push_back(_update(roots[root_id], 0, n, [&](T &x){ 41 | x = op(x, val); 42 | })); 43 | } 44 | pair prefix_search(auto&& f, int time, int start_index = 0){ 45 | return _prefix_search(f, start_index, e, roots[time], 0, n); 46 | } 47 | pair _prefix_search(auto&& f, int start_index, T prefix_value, int node_id, int l, int r){ 48 | if(r <= start_index) return pair(prefix_value, r); 49 | int mid = (l + r) / 2; 50 | if(l + 1 == r){ 51 | return pair(op(prefix_value, nodes[node_id].data), r); 52 | } 53 | if(start_index <= l && f(op(prefix_value, nodes[node_id].data))){ 54 | return pair(op(prefix_value, nodes[node_id].data), r); 55 | } 56 | auto [left_value, left_lim] = _prefix_search(f, start_index, prefix_value, nodes[node_id].l, l, mid); 57 | if(left_lim != mid) return pair(left_value, left_lim); 58 | if(!f(left_value)) return pair(left_value, left_lim); 59 | prefix_value = left_value; 60 | return _prefix_search(f, start_index, prefix_value, nodes[node_id].r, mid, r); 61 | 62 | } 63 | int time(){ 64 | return roots.size() - 1; 65 | } 66 | private: 67 | int _index; 68 | int _update(int node_id, int l, int r, auto&& apply){ 69 | assert(l <= _index && _index < r); 70 | assert(node_id != -1); 71 | int new_node_id = nodes.size(); 72 | nodes.push_back(nodes[node_id]); 73 | if(l + 1 == r){ 74 | assert(l == _index); 75 | apply(nodes[new_node_id].data); 76 | return new_node_id; 77 | } 78 | int mid = (l + r) / 2; 79 | assert(nodes[new_node_id].l != -1); 80 | assert(nodes[new_node_id].r != -1); 81 | if(_index < mid){ 82 | assert(l <= _index && _index < mid); 83 | nodes[new_node_id].l = _update(nodes[new_node_id].l, l, mid, apply); 84 | } 85 | else{ 86 | assert(mid <= _index && _index < r); 87 | nodes[new_node_id].r = _update(nodes[new_node_id].r, mid, r, apply); 88 | } 89 | eval_node(new_node_id); 90 | return new_node_id; 91 | } 92 | int _ql, _qr; 93 | T _query(int node_id, int l, int r){ 94 | if(node_id == -1) return e; 95 | if(_qr <= l || _ql >= r) return e; 96 | if(_ql <= l && r <= _qr) return nodes[node_id].data; 97 | int mid = (l + r) / 2; 98 | if(_ql >= mid) return _query(nodes[node_id].r, mid, r); 99 | if(_qr <= mid) return _query(nodes[node_id].l, l, mid); 100 | return op(_query(nodes[node_id].l, l, mid), _query(nodes[node_id].r, mid, r)); 101 | } 102 | void eval_node(int node_id){ 103 | int l = nodes[node_id].l, r = nodes[node_id].r; 104 | if(l != -1) nodes[node_id].data = nodes[l].data; 105 | if(r != -1) nodes[node_id].data = op(nodes[node_id].data, nodes[r].data); 106 | } 107 | int _build(int l, int r, auto&& index_val){ 108 | if(l == r) return -1; 109 | int node_id = nodes.size(); 110 | nodes.push_back({e, -1, -1}); 111 | if(l + 1 == r){ 112 | nodes[node_id].data = index_val(l); 113 | return node_id; 114 | } 115 | int mid = (l + r) / 2; 116 | nodes[node_id].l = _build(l, mid, index_val); 117 | nodes[node_id].r = _build(mid, r, index_val); 118 | eval_node(node_id); 119 | assert(nodes[node_id].l != -1); 120 | assert(nodes[node_id].r != -1); 121 | return node_id; 122 | } 123 | }; 124 | --------------------------------------------------------------------------------