├── .DS_Store ├── .gitignore ├── DS ├── BIT.cpp ├── CentroidDecomposition.cpp ├── DSU.cpp ├── DescartesTree.cpp ├── HLD.cpp ├── Heap.cpp ├── LSD.cpp ├── LichaoSegmentTree.cpp ├── Link-Cut Tree.cpp ├── Mo.cpp ├── Monotone Deque.cpp ├── Monotone Stack.cpp ├── PersistentDSU.cpp ├── PersistentSegmentTree.cpp ├── PersistentTrie.cpp ├── QMo.cpp ├── QTreeMo.cpp ├── SegmentTree.cpp ├── SegmentTreeBeats.cpp ├── SegmentTreeMerge.cpp ├── SparseTable.cpp ├── Splay.cpp ├── Treap.cpp ├── TreeDSU.cpp ├── TreeMo.cpp ├── VirtualTree.cpp └── Young Tableaux.cpp ├── Geometry ├── Basics.cpp ├── ConvexHull.cpp ├── Stereometry.cpp └── jly.cpp ├── Graph ├── .DS_Store ├── Flow and cut algorithms │ ├── Dinic.cpp │ ├── FordFulkerson.cpp │ ├── GomoryHuTree.cpp │ ├── MinCostFlow(SPFA).cpp │ └── MinCostFlow.cpp ├── Matching algorithms │ ├── BipartiteMatching.cpp │ ├── CommonMatching.cpp │ ├── HopcroftKarp.cpp │ ├── KuhnMunkres.cpp │ └── LexicoMin.cpp ├── Minimum Spanning Tree Algorithms │ ├── Kruskal.cpp │ ├── PrimI.cpp │ └── PrimII.cpp ├── Others │ ├── BipartiteEdgeColoring.cpp │ ├── BlockCutTree.cpp │ ├── BridgeTree.cpp │ ├── ChordalGraph.cpp │ ├── DominatorTree.cpp │ ├── DynamicBridge.cpp │ ├── DynamicConnectivity.cpp │ ├── EarDecomposition.cpp │ ├── Eulerian.cpp │ ├── Kosaraju.cpp │ ├── LCA.cpp │ ├── LCArmq.cpp │ ├── MinimumArborescence.cpp │ ├── MinimumDiameterSpanningTree.cpp │ ├── SquareCount.cpp │ ├── Tarjan.cpp │ ├── TopologicalSort.cpp │ ├── TreeChainIntersection.cpp │ └── TriangleCount.cpp └── Shortest Path Algorithms │ ├── BellmanFord.cpp │ ├── DijkstraI.cpp │ ├── DijkstraII.cpp │ ├── FloydWarshall.cpp │ └── SPFA.cpp ├── Math ├── Berlekamp-Massey.cpp ├── BigNum.cpp ├── CRT.cpp ├── DIVCNT1.cpp ├── Determinant.cpp ├── Eratosthenes.cpp ├── Euclid.cpp ├── Euler.cpp ├── EulerSieve.cpp ├── ExtLucas.cpp ├── Extgcd.cpp ├── FFT.cpp ├── FWT.cpp ├── Farey.cpp ├── FastMultiplication.cpp ├── GaussJordan.cpp ├── Interpolation.cpp ├── LU.cpp ├── LinearBasis.cpp ├── LinearCongruence.cpp ├── Matrix.cpp ├── MillerRabin.cpp ├── Mobius.cpp ├── Mod.cpp ├── NTT.cpp ├── Pell.cpp ├── PohligHellman.cpp ├── Points In A Circle.cpp ├── PollardRho.cpp ├── PolyOp.cpp ├── PolySum.cpp ├── PowMod.cpp ├── PowerTower.cpp ├── PrimeCount.cpp ├── PrimitiveRoot.cpp ├── SchreierSims.cpp ├── SegmentSieve.cpp ├── Simpson.cpp ├── StirlingI.cpp ├── StirlingIIM.cpp ├── StirlingIIS.cpp ├── Strassen.cpp ├── SubsetConvolution.cpp ├── SumMiu.cpp ├── SumPhi.cpp └── TonelliShanks.cpp ├── Others ├── ConvexHullTrick.cpp ├── DynamicConvexHullTrick.cpp ├── DynamicDP.cpp ├── IsotonicRegression.cpp ├── Knuth.cpp ├── MatroidIntersection.cpp ├── MultipleBackpack.cpp ├── NimMultiplication.cpp ├── SMAWK.cpp ├── SOS.cpp ├── Simplex.cpp ├── SlopeTrick.cpp ├── Subset.cpp ├── SurrealNumber.cpp ├── WeightedMatroidIntersection.cpp └── whatday.cpp ├── README.md ├── String ├── ACAM.cpp ├── GSAM.cpp ├── Hash.cpp ├── KMP.cpp ├── PAM.cpp ├── SA.cpp ├── SAIS.cpp ├── SAM.cpp ├── Trie.cpp └── manacher.cpp └── template.pdf /.DS_Store: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wcysai/CodeTemplates/c958bbce705abaecaca57c123bc052a1eee513c4/.DS_Store -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Prerequisites 2 | *.d 3 | 4 | # Compiled Object files 5 | *.slo 6 | *.lo 7 | *.o 8 | *.obj 9 | 10 | # Precompiled Headers 11 | *.gch 12 | *.pch 13 | 14 | # Compiled Dynamic libraries 15 | *.so 16 | *.dylib 17 | *.dll 18 | 19 | # Fortran module files 20 | *.mod 21 | *.smod 22 | 23 | # Compiled Static libraries 24 | *.lai 25 | *.la 26 | *.a 27 | *.lib 28 | 29 | # Executables 30 | *.exe 31 | *.out 32 | *.app 33 | -------------------------------------------------------------------------------- /DS/BIT.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #define MAXN 100000 3 | #define MAXLOGN 20 4 | #define INF 1000000000 5 | using namespace std; 6 | int bit[2*MAXN+1],n; 7 | int sum(int i) 8 | { 9 | int s=0; 10 | while(i>0) 11 | { 12 | s+=bit[i]; 13 | i-=i&-i; 14 | } 15 | return s; 16 | } 17 | void add(int i,int x) 18 | { 19 | while(i<=n) 20 | { 21 | bit[i]+=x; 22 | i+=i&-i; 23 | } 24 | } 25 | int bisearch(int v) 26 | { 27 | int sum=0,pos=0; 28 | for(int i=MAXLOGN;i>=0;i--) 29 | { 30 | if(pos+(1< 2 | #define MAXN 100005 3 | #define INF 1000000000 4 | #define MOD 1000000007 5 | #define F first 6 | #define S second 7 | using namespace std; 8 | typedef long long ll; 9 | typedef pair P; 10 | struct edge{int to,cost;}; 11 | int N,K; 12 | vector G[MAXN]; 13 | bool centroid[MAXN]; 14 | int sz[MAXN],deep[MAXN],d[MAXN]; 15 | int ans; 16 | P getroot(int v,int p,int t)//search_centroid 17 | { 18 | P res=P(INT_MAX,-1); 19 | int m=0; 20 | sz[v]=1; 21 | for(int i=0;i<(int)G[v].size();i++) 22 | { 23 | int to=G[v][i].to; 24 | if(to==p||centroid[to]) continue; 25 | res=min(res,getroot(to,v,t)); 26 | m=max(m,sz[to]); 27 | sz[v]+=sz[to]; 28 | } 29 | m=max(m,t-sz[v]); 30 | res=min(res,P(m,v)); 31 | return res; 32 | } 33 | void getdeep(int v,int p)//enumerate path 34 | { 35 | deep[++deep[0]]=d[v]; 36 | for(int i=0;i<(int)G[v].size();i++) 37 | { 38 | int to=G[v][i].to; 39 | if(to==p||centroid[to]) continue; 40 | d[to]=d[v]+G[v][i].cost; 41 | getdeep(to,v); 42 | } 43 | } 44 | int cal(int v,int cost) 45 | { 46 | d[v]=cost;deep[0]=0; 47 | getdeep(v,0); 48 | sort(deep+1,deep+deep[0]+1); 49 | int l=1,r=deep[0],sum=0; 50 | while(l 2 | #define MAXN 100000 3 | using namespace std; 4 | int p[MAXN],r[MAXN]; 5 | void init(int n) 6 | { 7 | for(int i=0;i 2 | #define MAXN 100005 3 | #define INF 1000000000 4 | #define MOD 1000000007 5 | #define F first 6 | #define S second 7 | using namespace std; 8 | typedef long long ll; 9 | typedef pair P; 10 | int n,h[MAXN]; 11 | int st[MAXN],t; 12 | int fa[MAXN],ls[MAXN],rs[MAXN],root; 13 | int main() 14 | { 15 | for(int i=1;i<=n;i++) 16 | { 17 | while(t&&h[st[t-1]]>h[i]) ls[i]=st[--t]; 18 | if(t) rs[st[t-1]]=i; 19 | st[t++]=i; 20 | } 21 | for(int i=1;i<=n;i++) fa[ls[i]]=fa[rs[i]]=i; 22 | for(int i=1;i<=n;i++) if(!fa[i]) root=i; 23 | } 24 | -------------------------------------------------------------------------------- /DS/HLD.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #define MAXN 400005 3 | #define INF 1000000000 4 | #define MOD 1000000007 5 | #define F first 6 | #define S second 7 | using namespace std; 8 | typedef long long ll; 9 | typedef pair P; 10 | struct node 11 | { 12 | int l,r,maxi,sum; 13 | }; 14 | int tot,q,n,k,a[MAXN]; 15 | int pa[MAXN],dep[MAXN],sz[MAXN],wson[MAXN],top[MAXN],spos[MAXN],tpos[MAXN]; 16 | struct segtree 17 | { 18 | node seg[4*MAXN]; 19 | int id[MAXN]; 20 | void build(int k,int l,int r) 21 | { 22 | seg[k].l=l;seg[k].r=r; 23 | if(l==r) 24 | { 25 | seg[k].maxi=seg[k].sum=a[tpos[l]]; 26 | id[l]=k; 27 | return; 28 | } 29 | int mid=(l+r)/2; 30 | build(k*2,l,mid);build(k*2+1,mid+1,r); 31 | seg[k].maxi=max(seg[k*2].maxi,seg[k*2+1].maxi); 32 | seg[k].sum=seg[k*2].sum+seg[k*2+1].sum; 33 | } 34 | void update(int k,int x) 35 | { 36 | k=id[k]; 37 | seg[k].maxi=seg[k].sum=x; 38 | while(k>1) 39 | { 40 | k=k/2; 41 | seg[k].maxi=max(seg[k*2].maxi,seg[k*2+1].maxi); 42 | seg[k].sum=seg[k*2].sum+seg[k*2+1].sum; 43 | } 44 | } 45 | int query1(int k,int l,int r) 46 | { 47 | if(seg[k].l>r||seg[k].r=l&&seg[k].r<=r) return seg[k].maxi; 49 | return max(query1(k*2,l,r),query1(k*2+1,l,r)); 50 | } 51 | int query2(int k,int l,int r) 52 | { 53 | if(seg[k].l>r||seg[k].r=l&&seg[k].r<=r) return seg[k].sum; 55 | return query2(k*2,l,r)+query2(k*2+1,l,r); 56 | } 57 | int query_max(int l,int r) 58 | { 59 | return query1(1,l,r); 60 | } 61 | int query_sum(int l,int r) 62 | { 63 | return query2(1,l,r); 64 | } 65 | }tree; 66 | vector G[MAXN]; 67 | void dfs1(int v,int p,int d) 68 | { 69 | dep[v]=d;pa[v]=p;sz[v]=1; 70 | for(int i=0;i<(int)G[v].size();i++) 71 | { 72 | int to=G[v][i]; 73 | if(to==p) continue; 74 | dfs1(to,v,d+1); 75 | if(sz[to]>sz[wson[v]]) wson[v]=to; 76 | sz[v]+=sz[to]; 77 | } 78 | } 79 | void dfs2(int v,int p,int num) 80 | { 81 | top[v]=num; 82 | spos[v]=++tot; 83 | tpos[tot]=v; 84 | if(wson[v]) dfs2(wson[v],v,num); 85 | for(int i=0;i<(int)G[v].size();i++) 86 | { 87 | int to=G[v][i]; 88 | if(to==p||to==wson[v]) continue; 89 | dfs2(to,v,to); 90 | } 91 | } 92 | void init() 93 | { 94 | tot=0; 95 | memset(wson,0,sizeof(wson));//important when multiple test cases!!! 96 | dfs1(1,1,1); 97 | dfs2(1,0,1); 98 | tree.build(1,1,n); 99 | } 100 | void update(int k,int x) 101 | { 102 | tree.update(spos[k],x); 103 | } 104 | int query_max(int u,int v) 105 | { 106 | int res=-INF; 107 | while(top[u]!=top[v]) 108 | { 109 | if(dep[top[u]] 2 | #define MAXN 100005 3 | #define INF 1000000000 4 | #define MOD 1000000007 5 | #define F first 6 | #define S second 7 | using namespace std; 8 | typedef long long ll; 9 | typedef pair P; 10 | struct heap 11 | { 12 | priority_queue q1,q2; 13 | void push(int x) {q1.push(x);} 14 | void erase(int x) {q2.push(x);} 15 | int top() 16 | { 17 | while(q2.size()&&q1.top()==q2.top()) q1.pop(),q2.pop(); 18 | return q1.top(); 19 | } 20 | void pop() 21 | { 22 | while(q2.size()&&q1.top()==q2.top()) q1.pop(),q2.pop(); 23 | q1.pop(); 24 | } 25 | int size() 26 | { 27 | return q1.size()-q2.size(); 28 | } 29 | }; 30 | int main() 31 | { 32 | return 0; 33 | } 34 | -------------------------------------------------------------------------------- /DS/LSD.cpp: -------------------------------------------------------------------------------- 1 | //Yinchuan 2019 Regional E 2 | #pragma GCC optimize(3) 3 | #include 4 | #define MAXN 1000005 5 | #define INF 1000000000 6 | #define MOD 1000000007 7 | #define F first 8 | #define S second 9 | using namespace std; 10 | typedef long long ll; 11 | typedef unsigned long long ull; 12 | typedef pair P; 13 | int n,k,a[MAXN],len[MAXN],son[MAXN]; 14 | int st[MAXN],ed[MAXN]; 15 | int cnt[MAXN][4],save[MAXN][4]; 16 | ull ans[MAXN]; 17 | int curi,curj; 18 | ull res; 19 | vector G[MAXN]; 20 | void dfs(int v,int p) 21 | { 22 | for(auto to:G[v]) 23 | { 24 | if(to==p) continue; 25 | dfs(to,v); 26 | if(len[to]>len[son[v]]) son[v]=to; 27 | } 28 | len[v]=len[son[v]]+1; 29 | } 30 | void dfs2(int v,int p) 31 | { 32 | if(son[v]) 33 | { 34 | st[son[v]]=st[v]+1; 35 | dfs2(son[v],v); 36 | ed[v]=ed[son[v]]; 37 | for(int i=0;i<4;i++) 38 | { 39 | cnt[v][i]=cnt[son[v]][i]; 40 | save[st[v]][i]=0; 41 | } 42 | } 43 | else 44 | { 45 | ed[v]=st[v]; 46 | for(int i=0;i<4;i++) 47 | { 48 | cnt[v][i]=0; 49 | save[st[v]][i]=0; 50 | } 51 | } 52 | int x=(((a[v]>>curi)&1)<<1)+((a[v]>>curj)&1); 53 | save[st[v]][x]=1; 54 | cnt[v][x]++; 55 | while(ed[v]-st[v]>k) 56 | { 57 | for(int i=0;i<4;i++) cnt[v][i]-=save[ed[v]][i]; 58 | ed[v]--; 59 | } 60 | for(auto to:G[v]) 61 | { 62 | if(to==p||to==son[v]) continue; 63 | st[to]=ed[v]+1; 64 | dfs2(to,v); 65 | for(int i=st[to];i<=ed[to]&&i-st[to]<=k;i++) 66 | for(int j=0;j<4;j++) 67 | { 68 | save[i-st[to]+1+st[v]][j]+=save[i][j]; 69 | cnt[v][j]+=save[i][j]; 70 | } 71 | } 72 | ans[v]+=res*cnt[v][0]*cnt[v][3]; 73 | ans[v]+=res*cnt[v][1]*cnt[v][2]; 74 | } 75 | int main() 76 | { 77 | scanf("%d%d",&n,&k); 78 | for(int i=1;i<=n;i++) scanf("%d",&a[i]); 79 | for(int i=2;i<=n;i++) 80 | { 81 | int f; 82 | scanf("%d",&f); 83 | G[f].push_back(i); 84 | G[i].push_back(f); 85 | } 86 | dfs(1,0); 87 | for(curi=0;curi<30;curi++) 88 | for(curj=0;curj<=curi;curj++) 89 | { 90 | if(curi==curj) res=1ULL<<(curi+curj); else res=1ULL<<(curi+curj+1); 91 | st[1]=1; 92 | dfs2(1,0); 93 | } 94 | for(int i=1;i<=n;i++) printf("%llu\n",ans[i]); 95 | return 0; 96 | } 97 | 98 | 99 | -------------------------------------------------------------------------------- /DS/LichaoSegmentTree.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #define MAXN 80005 3 | #define MAXM 10000005 4 | #define MAXT 1000000001 5 | #define INF 1000000000000000000LL 6 | #define MOD 1000000007 7 | #define F first 8 | #define S second 9 | int n,q,tot,lson[MAXM],rson[MAXM]; 10 | bool has[MAXM]; 11 | P ans[MAXM]; 12 | ll f(P p,int x) 13 | { 14 | return 1LL*p.F*x+p.S; 15 | } 16 | void insert(int &k,int l,int r,int x,int y,P p) 17 | { 18 | if(l>y||x>r) return; 19 | if(!k) k=++tot; 20 | has[k]=false; 21 | if(l>=x&&r<=y) 22 | { 23 | if(!has[k]) 24 | { 25 | has[k]=true; 26 | ans[k]=p; 27 | return; 28 | } 29 | ll trl=f(ans[k],l),trr=f(ans[k],r); 30 | ll vl=f(p,l),vr=f(p,r); 31 | if(trl<=vl&&trr<=vr) return; 32 | if(trl>=vl&&trr>=vr) {ans[k]=p; return;} 33 | int mid=(l+r)/2; 34 | if(trl>=vl) swap(ans[k],p); 35 | if(f(ans[k],mid)<=f(p,mid)) insert(rson[k],mid+1,r,x,y,p); 36 | else swap(ans[k],p),insert(lson[k],l,mid,x,y,p); 37 | return; 38 | } 39 | int mid=(l+r)/2; 40 | insert(lson[k],l,mid,x,y,p); insert(rson[k],mid+1,r,x,y,p); 41 | } 42 | ll query(int &k,int l,int r,int x) 43 | { 44 | if(!k) return INF; 45 | ll res=(!has[k]?INF:f(ans[k],x)); 46 | if(l==r) return res; 47 | int mid=(l+r)/2; 48 | if(x<=mid) return min(res,query(lson[k],l,mid,x)); 49 | else return min(res,query(rson[k],mid+1,r,x)); 50 | } 51 | -------------------------------------------------------------------------------- /DS/Link-Cut Tree.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #define MAXN 300005 3 | #define INF 1000000000 4 | #define MOD 1000000007 5 | #define F first 6 | #define S second 7 | using namespace std; 8 | typedef long long ll; 9 | typedef pair P; 10 | #define lc t[x].ch[0] 11 | #define rc t[x].ch[1] 12 | #define pa t[x].fa 13 | typedef long long ll; 14 | namespace lct 15 | { 16 | struct meow{int ch[2], fa, rev, sum, w;} t[2*MAXN]; 17 | inline int wh(int x) {return t[pa].ch[1] == x;} 18 | inline int isr(int x) {return t[pa].ch[0] != x && t[pa].ch[1] != x;} 19 | inline void update(int x) {t[x].sum = t[lc].sum ^ t[rc].sum ^ t[x].w;} 20 | inline void rever(int x) {t[x].rev ^= 1; swap(lc, rc);} 21 | inline void pushdown(int x) 22 | { 23 | if(t[x].rev) 24 | { 25 | if(lc) rever(lc); 26 | if(rc) rever(rc); 27 | t[x].rev = 0; 28 | } 29 | } 30 | void pd(int x) {if(!isr(x)) pd(pa); pushdown(x);} 31 | inline void rotate(int x) 32 | { 33 | int f=t[x].fa, g=t[f].fa, c=wh(x); 34 | if(!isr(f)) t[g].ch[wh(f)]=x; 35 | t[x].fa=g; 36 | t[f].ch[c] = t[x].ch[c^1]; t[t[f].ch[c]].fa=f; 37 | t[x].ch[c^1] = f; t[f].fa=x; 38 | update(f); update(x); 39 | } 40 | inline void splay(int x) 41 | { 42 | pd(x); 43 | for(; !isr(x); rotate(x)) 44 | if(!isr(pa)) rotate( wh(pa)==wh(x) ? pa : x ); 45 | } 46 | 47 | inline void access(int x) 48 | { 49 | for(int y=0; x; y=x, x=pa) splay(x), rc=y, update(x); 50 | } 51 | inline void maker(int x) 52 | { 53 | access(x); splay(x); rever(x); 54 | } 55 | inline int findr(int x) 56 | { 57 | access(x); splay(x); 58 | while(lc) pushdown(x), x=lc; 59 | return x; 60 | } 61 | inline void link(int x, int y) 62 | { 63 | maker(x); 64 | if(findr(y)!=x) t[x].fa=y; 65 | } 66 | inline void cut(int x, int y) 67 | { 68 | maker(x); 69 | if(findr(y)==x&&t[x].fa==y&&t[y].ch[0]==x&&!t[y].ch[1]) 70 | { 71 | t[x].fa=t[y].ch[0]=0; 72 | update(y); 73 | } 74 | } 75 | inline void split(int x, int y) 76 | { 77 | maker(x); access(y); splay(y); 78 | } 79 | } using lct::findr; 80 | 81 | int n, Q, op, x, y; 82 | int main() 83 | { 84 | scanf("%d%d",&n,&Q); 85 | for(int i=1; i<=n; i++) scanf("%d",&lct::t[i].w); 86 | for(int i=1; i<=Q; i++) 87 | { 88 | scanf("%d%d%d",&op,&x,&y); 89 | if(op==0) lct::split(x, y), printf("%d\n", lct::t[y].sum); 90 | if(op==1) lct::link(x, y); 91 | if(op==2) lct::cut(x, y); 92 | if(op==3) lct::t[x].w=y,lct::splay(x); 93 | } 94 | } 95 | -------------------------------------------------------------------------------- /DS/Mo.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #define MAXN 100005 3 | #define MAXM 100005 4 | using namespace std; 5 | struct query 6 | { 7 | int l,r,id; 8 | }save[MAXM]; 9 | int cnt[MAXN],a[MAXN],out[MAXN]; 10 | int n,m,ans,block; 11 | bool cmp(query x,query y) 12 | { 13 | if(x.l/block!=y.l/block) return x.l/blocky.r; else return x.rl) add(--cl); 32 | while(clr) del(cr--); 34 | } 35 | int main() 36 | { 37 | scanf("%d %d",&n,&m); 38 | block=(int)sqrt(n); 39 | for(int i=1;i<=n;i++) 40 | { 41 | scanf("%d",&a[i]); 42 | if(a[i]>100000) a[i]=100001; 43 | } 44 | for(int i=0;i 2 | #define MAXN 100005 3 | using namespace std; 4 | int n,k; 5 | int a[MAXN]; 6 | int b[MAXN]; 7 | int deq[MAXN]; 8 | void solve() 9 | { 10 | int s=0,t=0; 11 | for(int i=0;i=a[i]) t--; 14 | deq[t++]=i; 15 | if(i-k+1>=0) 16 | { 17 | b[i-k+1]=a[deq[s]]; 18 | if(deq[s]==i-k+1) 19 | { 20 | s++; 21 | } 22 | } 23 | } 24 | for(int i=0;i<=n-k;i++) 25 | { 26 | printf("%d%c",b[i],i==n-k?'\n':' '); 27 | } 28 | } 29 | int main() 30 | { 31 | scanf("%d %d",&n,&k); 32 | for(int i=0;i 2 | #define MAXN 100000 3 | using namespace std; 4 | int n; 5 | int h[MAXN]; 6 | int L[MAXN],R[MAXN]; 7 | int st[MAXN]; 8 | void solve() 9 | { 10 | int t=0; 11 | for(int i=0;i0&&h[st[t-1]]>=h[i]) t--; 14 | L[i]=t==0?0:(st[t-1]+1); 15 | st[t++]=i; 16 | } 17 | t=0; 18 | for(int i=n-1;i>=0;i--) 19 | { 20 | while(t>0&&h[st[t-1]]>=h[i]) t--; 21 | R[i]=t==0?n:st[t-1]; 22 | st[t++]=i; 23 | } 24 | long long res=0; 25 | for(int i=0;i 2 | #define MAXN 100005 3 | #define MAXM 2000005 4 | #define INF 1000000000 5 | #define MOD 1000000007 6 | #define F first 7 | #define S second 8 | using namespace std; 9 | typedef long long ll; 10 | typedef pair P; 11 | int n,m,tot,root[MAXN]; 12 | int lson[MAXM],rson[MAXN],p[MAXM],rk[MAXM]; 13 | void build(int &k,int l,int r) 14 | { 15 | k=++tot; 16 | if(l==r) {p[k]=l; return;} 17 | int mid=(l+r)/2; 18 | build(lson[k],l,mid);build(rson[k],mid+1,r); 19 | } 20 | void insert(int &k,int last,int l,int r,int pos,int val) 21 | { 22 | k=++tot; 23 | if(l==r) {p[k]=val; rk[k]=rk[last]; return;} 24 | lson[k]=lson[last];rson[k]=rson[last]; 25 | int mid=(l+r)/2; 26 | if(pos<=mid) insert(lson[k],lson[last],l,mid,pos,val); 27 | else insert(rson[k],rson[last],mid+1,r,pos,val); 28 | } 29 | int query(int k,int l,int r,int pos) 30 | { 31 | if(l==r) return k; 32 | int mid=(l+r)/2; 33 | if(pos<=mid) return query(lson[k],l,mid,pos); 34 | else return query(rson[k],mid+1,r,pos); 35 | } 36 | void add(int k,int l,int r,int pos) 37 | { 38 | if(l==r) {rk[k]++; return;} 39 | int mid=(l+r)/2; 40 | if(pos<=mid) add(lson[k],l,mid,pos); 41 | else add(rson[k],mid+1,r,pos); 42 | } 43 | int find(int k,int x) 44 | { 45 | int q=query(k,1,n,x); 46 | if(x==p[q]) return q; 47 | return find(k,p[q]); 48 | } 49 | int main() 50 | { 51 | return 0; 52 | } 53 | 54 | -------------------------------------------------------------------------------- /DS/PersistentSegmentTree.cpp: -------------------------------------------------------------------------------- 1 | #pragma GCC optimize(3) 2 | #include 3 | #define MAXN 100005 4 | #define MAXM 2000005 5 | #define INF 1000000000 6 | #define MOD 1000000007 7 | #define F first 8 | #define S second 9 | using namespace std; 10 | typedef long long ll; 11 | typedef pair P; 12 | int n,q,tot,cnt,a[MAXN],root[MAXN]; 13 | int lson[MAXM],rson[MAXM],mx[MAXM]; 14 | void merge(int k) 15 | { 16 | mx[k]=max(mx[lson[k]],mx[rson[k]]); 17 | } 18 | void build(int &k,int l,int r) 19 | { 20 | k=++tot; 21 | if(l==r) {mx[k]=a[l]; return;} 22 | int mid=(l+r)/2; 23 | build(lson[k],l,mid);build(rson[k],mid+1,r); 24 | merge(k); 25 | } 26 | void insert(int &k,int last,int l,int r,int p,int v) 27 | { 28 | k=++tot; 29 | mx[k]=mx[last]; 30 | if(l==r) {mx[k]=v; return;} 31 | lson[k]=lson[last];rson[k]=rson[last]; 32 | int mid=(l+r)/2; 33 | if(p<=mid) insert(lson[k],lson[last],l,mid,p,v); 34 | else insert(rson[k],rson[last],mid+1,r,p,v); 35 | merge(k); 36 | } 37 | int query(int &k,int l,int r,int x,int y) 38 | { 39 | if(!k) return 0; 40 | if(l>y||r=x&&r<=y) return mx[k]; 42 | int mid=(l+r)/2; 43 | return max(query(lson[k],l,mid,x,y),query(rson[k],mid+1,r,x,y)); 44 | } 45 | int main() 46 | { 47 | scanf("%d%d",&n,&q); 48 | for(int i=1;i<=n;i++) 49 | scanf("%d",&a[i]); 50 | build(root[++cnt],1,n); 51 | for(int i=1;i<=q;i++) 52 | { 53 | int type,k,x,y; 54 | scanf("%d%d%d%d",&type,&k,&x,&y); 55 | if(type==1) insert(root[++cnt],root[k],1,n,x,y); 56 | else printf("%d\n",query(root[k],1,n,x,y)); 57 | } 58 | return 0; 59 | } 60 | 61 | 62 | 63 | -------------------------------------------------------------------------------- /DS/PersistentTrie.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #define MAXN 100005 3 | #define MAXM 2000005 4 | #define INF 1000000000 5 | #define MOD 1000000007 6 | #define F first 7 | #define S second 8 | using namespace std; 9 | typedef long long ll; 10 | typedef pair P; 11 | int n,k,a[MAXN],tot; 12 | int trie[MAXM][2],root[MAXN],sz[MAXM]; 13 | int newnode() 14 | { 15 | ++tot; 16 | trie[tot][0]=trie[tot][1]=0; 17 | return tot; 18 | } 19 | void insert(int u,int v,int x) 20 | { 21 | int now1=root[u]=newnode(),now2=root[v]; 22 | for(int i=18;i>=0;i--) 23 | { 24 | int id=(x>>i)&1; 25 | trie[now1][id]=newnode(); 26 | trie[now1][!id]=trie[now2][!id]; 27 | now1=trie[now1][id];now2=trie[now2][id]; 28 | sz[now1]=sz[now2]+1; 29 | } 30 | } 31 | int query(int l,int r,int x) 32 | { 33 | int res=0; 34 | int now1=root[r+1],now2=root[l]; 35 | for(int i=18;i>=0;i--) 36 | { 37 | int id=(x>>i)&1; 38 | if(sz[trie[now1][!id]]-sz[trie[now2][!id]]>0) 39 | { 40 | res+=(1< 2 | #define MAXN 50005 3 | #define MAXM 1000005 4 | #define INF 1000000000 5 | #define MOD 1000000007 6 | #define F first 7 | #define S second 8 | using namespace std; 9 | typedef long long ll; 10 | typedef pair P; 11 | const int blocks=1200; 12 | int tot,tcnt,qid; 13 | struct query 14 | { 15 | int l,r,ti,id; 16 | }Q[MAXN]; 17 | int n,q,cnt[MAXM],ans,a[MAXN]; 18 | P change[MAXN]; 19 | int res[MAXN]; 20 | bool cmp(query x,query y) 21 | { 22 | if(x.l/blocks!=y.l/blocks) return x.l/blocksy.ti; else return x.ti=Q[num].l&&change[ti].F<=Q[num].r) 39 | { 40 | cnt[a[change[ti].F]]--; 41 | if(!cnt[a[change[ti].F]]) ans--; 42 | if(!cnt[change[ti].S]) ans++; 43 | cnt[change[ti].S]++; 44 | } 45 | swap(a[change[ti].F],change[ti].S); 46 | } 47 | char ch[2]; 48 | int main() 49 | { 50 | scanf("%d%d",&n,&q); 51 | for(int i=1;i<=n;i++) scanf("%d",&a[i]); 52 | for(int i=1;i<=q;i++) 53 | { 54 | int l,r; 55 | scanf("%s%d%d",ch,&l,&r); 56 | if(ch[0]=='Q') Q[++tot]=(query){l,r,tcnt,++qid}; 57 | else change[++tcnt]=P(l,r); 58 | } 59 | sort(Q+1,Q+tot+1,cmp); 60 | int l=1,r=0,ti=0; 61 | for(int i=1;i<=tot;i++) 62 | { 63 | while(l>Q[i].l) add(--l); 64 | while(lQ[i].r) del(r--); 67 | while(tiQ[i].ti) modify(ti--,i); 69 | res[Q[i].id]=ans; 70 | } 71 | for(int i=1;i<=qid;i++) printf("%d\n",res[i]); 72 | return 0; 73 | } 74 | -------------------------------------------------------------------------------- /DS/SegmentTree.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #define MAXN 500030 3 | using namespace std; 4 | int n,m,h[MAXN],c[MAXN]; 5 | struct node 6 | { 7 | int l,r,left,right,lazy; 8 | }seg[4*MAXN]; 9 | bool cmp(int x,int y) 10 | { 11 | return x>y; 12 | } 13 | void build(int k,int l,int r) 14 | { 15 | seg[k].l=l; 16 | seg[k].r=r; 17 | seg[k].lazy=0; 18 | if(l==r) 19 | { 20 | seg[k].left=seg[k].right=h[l]; 21 | return; 22 | } 23 | int mid=(l+r)/2; 24 | build(k*2,l,mid); 25 | build(k*2+1,mid+1,r); 26 | seg[k].left=seg[k*2].left; 27 | seg[k].right=seg[k*2+1].right; 28 | } 29 | void Lazy(int k) 30 | { 31 | if(seg[k].l==seg[k].r) 32 | { 33 | seg[k].lazy=0; 34 | return; 35 | } 36 | seg[k*2].left-=seg[k].lazy; 37 | seg[k*2].right-=seg[k].lazy; 38 | seg[k*2+1].left-=seg[k].lazy; 39 | seg[k*2+1].right-=seg[k].lazy; 40 | seg[k*2].lazy+=seg[k].lazy; 41 | seg[k*2+1].lazy+=seg[k].lazy; 42 | seg[k].lazy=0; 43 | } 44 | bool update(int k,int l,int r) 45 | { 46 | if(rr||seg[k].r=l&&seg[k].r<=r) 49 | { 50 | seg[k].lazy++; 51 | seg[k].left--; 52 | seg[k].right--; 53 | return (seg[k].left>=0&&seg[k].right>=0); 54 | } 55 | if(seg[k].lazy) Lazy(k); 56 | bool f1=update(k*2,l,r); 57 | bool f2=update(k*2+1,l,r); 58 | seg[k].left=seg[k*2].left; 59 | seg[k].right=seg[k*2+1].right; 60 | return(f1&&f2); 61 | } 62 | int findval(int k,int l,int r,int x) 63 | { 64 | if(seg[k].lazy) Lazy(k); 65 | if(l==r) return seg[k].left; 66 | int mid=(l+r)/2; 67 | if(x>mid) return findval(k*2+1,mid+1,r,x); 68 | return findval(k*2,l,mid,x); 69 | } 70 | int findleft(int k,int l,int r,int x) 71 | { 72 | if(seg[k].lazy) Lazy(k); 73 | if(l==r) return l; 74 | int mid=(l+r)/2; 75 | if(seg[k*2].right<=x) return findleft(k*2,l,mid,x); 76 | return findleft(k*2+1,mid+1,r,x); 77 | } 78 | int findright(int k,int l,int r,int x) 79 | { 80 | if(seg[k].lazy) Lazy(k); 81 | if(l==r) return r; 82 | int mid=(l+r)/2; 83 | if(seg[k*2].lazy) Lazy(k*2); 84 | if(seg[k*2+1].lazy) Lazy(k*2+1); 85 | if(seg[k*2+1].left>=x) return findright(k*2+1,mid+1,r,x); 86 | return findright(k*2,l,mid,x); 87 | } 88 | int main() 89 | { 90 | scanf("%d%d",&n,&m); 91 | for(int i=1;i<=n;i++) 92 | scanf("%d",&h[i]); 93 | sort(h+1,h+n+1,cmp); 94 | for(int i=0;in) break; 101 | int x=findval(1,1,n,c[cnt]); 102 | int a=findleft(1,1,n,x); 103 | int b=findright(1,1,n,x); 104 | bool f1=update(1,1,a-1),f2=update(1,b-c[cnt]+a,b); 105 | if(!(f1&&f2)) break; 106 | cnt++; 107 | if(cnt>=m) break; 108 | } 109 | printf("%d\n",cnt); 110 | return 0; 111 | } 112 | -------------------------------------------------------------------------------- /DS/SegmentTreeBeats.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #define MAXN 1000005 3 | #define INF 1000000000 4 | #define MOD 1000000007 5 | #define F first 6 | #define S second 7 | using namespace std; 8 | typedef long long ll; 9 | typedef pair P; 10 | struct node 11 | { 12 | ll l,r,sum,maxx,secx,maxnum,lazy; 13 | }seg[4*MAXN]; 14 | ll t,n,m,a[MAXN]; 15 | void Lazy(ll k) 16 | { 17 | if(seg[k].l==seg[k].r||seg[k].lazy==INT_MAX) return; 18 | if(seg[k*2].lazy>=seg[k].lazy&&seg[k*2].maxx>seg[k].lazy) 19 | { 20 | seg[k*2].sum-=(seg[k*2].maxx-seg[k].lazy)*seg[k*2].maxnum; 21 | seg[k*2].maxx=seg[k].lazy; 22 | seg[k*2].lazy=seg[k].lazy; 23 | } 24 | if(seg[k*2+1].lazy>=seg[k].lazy&&seg[k*2+1].maxx>seg[k].lazy) 25 | { 26 | seg[k*2+1].sum-=(seg[k*2+1].maxx-seg[k].lazy)*seg[k*2+1].maxnum; 27 | seg[k*2+1].maxx=seg[k].lazy; 28 | seg[k*2+1].lazy=seg[k].lazy; 29 | } 30 | seg[k].lazy=INT_MAX; 31 | return; 32 | } 33 | void merge(ll k) 34 | { 35 | seg[k].sum=seg[k*2].sum+seg[k*2+1].sum; 36 | seg[k].maxx=max(seg[k*2].maxx,seg[k*2+1].maxx); 37 | ll res=0,ans=-1; 38 | if(seg[k*2].maxx==seg[k].maxx) res+=seg[k*2].maxnum; 39 | if(seg[k*2+1].maxx==seg[k].maxx) res+=seg[k*2+1].maxnum; 40 | seg[k].maxnum=res; 41 | if(seg[k*2].maxx!=seg[k].maxx) ans=max(ans,seg[k*2].maxx); 42 | if(seg[k*2].secx!=seg[k].maxx) ans=max(ans,seg[k*2].secx); 43 | if(seg[k*2+1].maxx!=seg[k].maxx) ans=max(ans,seg[k*2+1].maxx); 44 | if(seg[k*2+1].secx!=seg[k].maxx) ans=max(ans,seg[k*2+1].secx); 45 | seg[k].secx=ans; 46 | //printf("l=%lld r=%lld maxx=%lld secx=%lld maxnum=%lld sum=%lld lazy=%lld\n",seg[k].l,seg[k].r,seg[k].maxx,seg[k].secx,seg[k].maxnum,seg[k].sum,seg[k].lazy); 47 | } 48 | void build(ll k,ll l,ll r) 49 | { 50 | seg[k].l=l;seg[k].r=r;seg[k].lazy=INT_MAX; 51 | if(l==r) 52 | { 53 | seg[k].maxx=seg[k].sum=a[l]; 54 | seg[k].maxnum=1; 55 | seg[k].secx=-1; 56 | return; 57 | } 58 | ll mid=(l+r)/2; 59 | build(k*2,l,mid);build(k*2+1,mid+1,r); 60 | merge(k); 61 | } 62 | void update(ll k,ll l,ll r,ll x) 63 | { 64 | if(seg[k].l>r||seg[k].r=l&&seg[k].r<=r&&seg[k].secxr||seg[k].r=l&&seg[k].r<=r) return seg[k].maxx; 80 | Lazy(k); 81 | return max(query1(k*2,l,r),query1(k*2+1,l,r)); 82 | } 83 | ll query2(ll k,ll l,ll r) 84 | { 85 | if(seg[k].l>r||seg[k].r=l&&seg[k].r<=r) return seg[k].sum; 87 | Lazy(k); 88 | return query2(k*2,l,r)+query2(k*2+1,l,r); 89 | } 90 | int main() 91 | { 92 | scanf("%lld",&t); 93 | while(t--) 94 | { 95 | scanf("%lld%lld",&n,&m); 96 | for(ll i=1;i<=n;i++) scanf("%lld",&a[i]); 97 | build(1,1,n); 98 | for(ll i=1;i<=m;i++) 99 | { 100 | ll type,x,y,z; 101 | scanf("%lld",&type); 102 | if(type==0) 103 | { 104 | scanf("%lld%lld%lld",&x,&y,&z); 105 | update(1,x,y,z); 106 | } 107 | else if(type==1) 108 | { 109 | scanf("%lld%lld",&x,&y); 110 | printf("%lld\n",query1(1,x,y)); 111 | } 112 | else 113 | { 114 | scanf("%lld%lld",&x,&y); 115 | printf("%lld\n",query2(1,x,y)); 116 | } 117 | } 118 | } 119 | return 0; 120 | } -------------------------------------------------------------------------------- /DS/SegmentTreeMerge.cpp: -------------------------------------------------------------------------------- 1 | #pragma GCC optimize(3) 2 | #include 3 | #define MAXN 100005 4 | #define MAXM 2000005 5 | #define INF 1000000000 6 | #define MOD 1000000007 7 | #define F first 8 | #define S second 9 | using namespace std; 10 | typedef long long ll; 11 | typedef pair P; 12 | int n,sz,tot,root[MAXN],a[MAXN],ans[MAXN]; 13 | int cnt[MAXM],lson[MAXM],rson[MAXM]; 14 | vector G[MAXN]; 15 | vector v; 16 | //ask for how many a[j]=x) return cnt[k]; 55 | int mid=(l+r)/2; 56 | return query(lson[k],l,mid,x)+query(rson[k],mid+1,r,x); 57 | } 58 | void dfs(int v,int p) 59 | { 60 | for(auto to:G[v]) 61 | { 62 | if(to==p) continue; 63 | dfs(to,v); 64 | root[v]=merge(root[v],root[to],1,sz); 65 | } 66 | ans[v]=query(root[v],1,sz,a[v]+1); 67 | } 68 | int main() 69 | { 70 | scanf("%d",&n); 71 | for(int i=1;i<=n;i++) 72 | { 73 | scanf("%d",&a[i]); 74 | v.push_back(a[i]); 75 | } 76 | sort(v.begin(),v.end()); 77 | v.erase(unique(v.begin(),v.end()),v.end()); 78 | for(int i=1;i<=n;i++) a[i]=lower_bound(v.begin(),v.end(),a[i])-v.begin()+1; 79 | sz=(int)v.size(); 80 | for(int i=2;i<=n;i++) 81 | { 82 | int p;scanf("%d",&p); 83 | G[p].push_back(i);G[i].push_back(p); 84 | } 85 | for(int i=1;i<=n;i++) build(root[i],1,sz,a[i]); 86 | dfs(1,0); 87 | for(int i=1;i<=n;i++) printf("%d\n",ans[i]); 88 | return 0; 89 | } 90 | 91 | -------------------------------------------------------------------------------- /DS/SparseTable.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #define MAXN 100000 3 | using namespace std; 4 | int N,Q; 5 | int a[MAXN]; 6 | int st[MAXN][32]; 7 | int pre[MAXN]; 8 | void init(int n,int *arr) 9 | { 10 | pre[1]=0; 11 | for(int i=2;i<=n;i++) 12 | { 13 | pre[i]=pre[i-1]; 14 | if ((1<=0;--i) 17 | { 18 | st[i][0]=arr[i]; 19 | for(int j=1;(i+(1< 2 | #define MAXN 1000005 3 | #define INF 1000000000 4 | #define MOD 1000000007 5 | #define F first 6 | #define S second 7 | using namespace std; 8 | typedef long long ll; 9 | typedef pair P; 10 | int ch[MAXN][2],f[MAXN],size[MAXN],cnt[MAXN],key[MAXN]; 11 | int sz,root; 12 | inline void clear(int x) 13 | { 14 | ch[x][0]=ch[x][1]=f[x]=size[x]=cnt[x]=key[x]=0; 15 | } 16 | inline bool get(int x) 17 | { 18 | return ch[f[x]][1]==x; 19 | } 20 | inline void pushup(int x) 21 | { 22 | if (x) 23 | { 24 | size[x]=cnt[x]; 25 | if (ch[x][0]) size[x]+=size[ch[x][0]]; 26 | if (ch[x][1]) size[x]+=size[ch[x][1]]; 27 | } 28 | } 29 | inline void rotate(int x) 30 | { 31 | int old=f[x],oldf=f[old],whichx=get(x); 32 | ch[old][whichx]=ch[x][whichx^1]; f[ch[old][whichx]]=old; 33 | ch[x][whichx^1]=old; f[old]=x; 34 | f[x]=oldf; 35 | if (oldf) ch[oldf][ch[oldf][1]==old]=x; 36 | pushup(old); pushup(x); 37 | } 38 | inline void splay(int x,int goal=0) 39 | { 40 | for(int fa;(fa=f[x])!=goal;rotate(x)) 41 | if(f[fa]!=goal) rotate((get(x)==get(fa))?fa:x); 42 | if(goal==0) root=x; 43 | } 44 | inline void insert(int x) 45 | { 46 | if (root==0){sz++; ch[sz][0]=ch[sz][1]=f[sz]=0; root=sz; size[sz]=cnt[sz]=1; key[sz]=x; return;} 47 | int now=root,fa=0; 48 | while(1) 49 | { 50 | if (x==key[now]) 51 | { 52 | cnt[now]++; pushup(now); pushup(fa); splay(now); break; 53 | } 54 | fa=now; 55 | now=ch[now][key[now]1){cnt[root]--; pushup(root); return;} 110 | if (!ch[root][0]&&!ch[root][1]) {clear(root); root=0; return;} 111 | if (!ch[root][0]) 112 | { 113 | int oldroot=root; root=ch[root][1]; f[root]=0; clear(oldroot); return; 114 | } 115 | else if (!ch[root][1]) 116 | { 117 | int oldroot=root; root=ch[root][0]; f[root]=0; clear(oldroot); return; 118 | } 119 | int leftbig=pre(),oldroot=root; 120 | splay(leftbig); 121 | ch[root][1]=ch[oldroot][1]; 122 | f[ch[oldroot][1]]=root; 123 | clear(oldroot); 124 | pushup(root); 125 | } 126 | int main() 127 | { 128 | int n,opt,x; 129 | scanf("%d",&n); 130 | for (int i=1;i<=n;++i) 131 | { 132 | scanf("%d%d",&opt,&x); 133 | switch(opt) 134 | { 135 | case 1: insert(x); break; 136 | case 2: del(x); break; 137 | case 3: printf("%d\n",find(x)); break; 138 | case 4: printf("%d\n",findx(root,x)); break; 139 | case 5: insert(x); printf("%d\n",key[pre()]); del(x); break; 140 | case 6: insert(x); printf("%d\n",key[next()]); del(x); break; 141 | } 142 | } 143 | } 144 | 145 | -------------------------------------------------------------------------------- /DS/Treap.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #define MAXN 500005 3 | #define INF 1000000000 4 | #define F first 5 | #define S second 6 | #define ls t[o].ch[0] 7 | #define rs t[o].ch[1] 8 | using namespace std; 9 | typedef long long ll; 10 | typedef pair P; 11 | mt19937_64 rng(std::chrono::system_clock::now().time_since_epoch().count()); 12 | struct node 13 | { 14 | int ch[2],sz,val,lazy,pri,maxi; 15 | }; 16 | namespace treap 17 | { 18 | int root,tot; 19 | node t[MAXN]; 20 | void init() 21 | { 22 | root=0; 23 | t[root].ch[0]=t[root].ch[1]=0; 24 | tot=0; 25 | } 26 | int newnode(int val) 27 | { 28 | tot++; 29 | t[tot].val=val; t[tot].ch[0]=t[tot].ch[1]=0; 30 | t[tot].sz=1; t[tot].pri=rng(); t[tot].maxi=t[tot].lazy=0; 31 | return tot; 32 | } 33 | void pushup(int o) 34 | { 35 | t[o].sz=t[ls].sz+t[rs].sz+1; 36 | t[o].maxi=max(t[ls].maxi,t[rs].maxi); 37 | } 38 | void add(int o,int v) 39 | { 40 | if(!o) return; 41 | t[o].maxi+=v; t[o].lazy+=v; 42 | } 43 | void pushdown(int o) 44 | { 45 | if(!t[o].lazy) return; 46 | add(ls,t[o].lazy); add(rs,t[o].lazy); 47 | t[o].lazy=0; 48 | } 49 | P split(int o,int cnt) 50 | { 51 | if(!o) return P(0,0); 52 | pushdown(o); 53 | if(t[ls].sz>=cnt) 54 | { 55 | P p=split(ls,cnt); 56 | int tl=p.F,tr=p.S; 57 | ls=tr; pushup(o); 58 | return P(tl,o); 59 | } 60 | else 61 | { 62 | P p=split(rs,cnt-t[ls].sz-1); 63 | int tl=p.F,tr=p.S; 64 | rs=tl; pushup(o); 65 | return P(o,tr); 66 | } 67 | } 68 | int merge(int x,int y) 69 | { 70 | if(!x||!y) return x+y; 71 | if(t[x].pri=b) continue; 111 | int len=min(b-a,n-b+1); 112 | P p1=split(root,a-1); 113 | P p2=split(p1.S,len); 114 | P p3=split(p2.S,b-a-len); 115 | P p4=split(p3.S,len); 116 | root=merge(p1.F,merge(p4.F,merge(p3.F,merge(p2.F,p4.S)))); 117 | } 118 | print(root); 119 | return 0; 120 | } 121 | -------------------------------------------------------------------------------- /DS/TreeDSU.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #define MAXN 100005 3 | #define INF 1000000000 4 | #define MOD 1000000007 5 | #define F first 6 | #define S second 7 | using namespace std; 8 | typedef long long ll; 9 | typedef pair P; 10 | int n,t,c[MAXN],sz[MAXN],st[MAXN],ed[MAXN],cnt[MAXN],rev[MAXN]; 11 | vector G[MAXN]; 12 | void dfs(int v,int p) 13 | { 14 | st[v]=++t;rev[t]=v; 15 | sz[v]=1; 16 | for(int i=0;i<(int)G[v].size();i++) 17 | { 18 | if(G[v][i]==p) continue; 19 | dfs(G[v][i],v); 20 | sz[v]+=sz[G[v][i]]; 21 | } 22 | ed[v]=t; 23 | return; 24 | } 25 | void dfs2(int v,int p,bool keep) 26 | { 27 | int mx=-1,wson=-1; 28 | for(int i=0;i<(int)G[v].size();i++) 29 | { 30 | int to=G[v][i]; 31 | if(to==p) continue; 32 | if(sz[to]>mx) {mx=sz[to]; wson=to;} 33 | } 34 | for(int i=0;i<(int)G[v].size();i++) 35 | { 36 | int to=G[v][i]; 37 | if(to==p||to==wson) continue; 38 | dfs2(to,v,0); 39 | } 40 | if(wson!=-1) dfs2(wson,v,1); 41 | for(int i=0;i<(int)G[v].size();i++) 42 | { 43 | int to=G[v][i]; 44 | if(to==p||to==wson) continue; 45 | for(int j=st[to];j<=ed[to];j++) 46 | cnt[c[rev[j]]]++; 47 | } 48 | cnt[c[v]]++; 49 | //answer queries here 50 | if(!keep) 51 | { 52 | for(int j=st[v];j<=ed[v];j++) 53 | cnt[c[rev[j]]]--; 54 | } 55 | } 56 | int main() 57 | { 58 | scanf("%d",&n); 59 | for(int i=1;i<=n;i++) scanf("%d",&c[i]); 60 | for(int i=0;i 3 | #define MAXN 200005 4 | #define MAXM 200005 5 | #define MAXLOGN 20 6 | #define INF 1000000000 7 | #define MOD 1000000007 8 | #define F first 9 | #define S second 10 | using namespace std; 11 | typedef long long ll; 12 | typedef pair P; 13 | int n,q,tot,st[2*MAXN],ed[2*MAXN],loc[2*MAXN],val[MAXN]; 14 | vector dis; 15 | vector G[MAXN]; 16 | int spt[MAXLOGN+1][4*MAXN]; 17 | int vs[MAXN*2],depth[MAXN*2]; 18 | int id[MAXN],pos[2*MAXN],cnt[MAXN],now,sum; 19 | bool vis[MAXN]; 20 | vector v; 21 | void dfs(int v,int p,int d,int &k) 22 | { 23 | st[v]=++tot; loc[tot]=v; 24 | id[v]=k; 25 | vs[k]=v; 26 | depth[k++]=d; 27 | for(auto to:G[v]) 28 | { 29 | if(to==p) continue; 30 | dfs(to,v,d+1,k); 31 | vs[k]=v; 32 | depth[k++]=d; 33 | } 34 | ed[v]=++tot; 35 | loc[tot]=v; 36 | } 37 | void add_edge(int u,int v) 38 | { 39 | G[u].push_back(v); 40 | G[v].push_back(u); 41 | } 42 | int getMin(int x, int y) 43 | { 44 | return depth[x]=0); 92 | if(!cnt[val[x]]) now--; 93 | sum--; 94 | } 95 | vis[x]^=1; 96 | } 97 | int ans[MAXM]; 98 | const int blocks=200; 99 | int main() 100 | { 101 | scanf("%d%d",&n,&q); 102 | for(int i=1;i<=n;i++) 103 | { 104 | scanf("%d",&val[i]); 105 | dis.push_back(val[i]); 106 | } 107 | sort(dis.begin(),dis.end()); 108 | dis.erase(unique(dis.begin(),dis.end()),dis.end()); 109 | for(int i=1;i<=n;i++) val[i]=lower_bound(dis.begin(),dis.end(),val[i])-dis.begin(); 110 | for(int i=0;ist[v]) swap(u,v); 126 | int z=lca(u,v); 127 | if(z==u) Q[i].l=st[u],Q[i].r=st[v]; 128 | else Q[i].l=ed[u],Q[i].r=st[v],Q[i].z=z; 129 | } 130 | sort(Q+1,Q+q+1,cmp); 131 | int l=1,r=0; 132 | memset(cnt,0,sizeof(cnt)); 133 | memset(vis,false,sizeof(vis)); 134 | for(int i=1;i<=q;i++) 135 | { 136 | if(rQ[i].r) {for(;r>Q[i].r;r--) deal(loc[r]); } 138 | if(lQ[i].l) {for(l--;l>=Q[i].l;l--) deal(loc[l]); l++;} 140 | if(Q[i].z) deal(Q[i].z); 141 | ans[Q[i].id]=now; 142 | if(Q[i].z) deal(Q[i].z); 143 | } 144 | for(int i=1;i<=q;i++) printf("%d\n",ans[i]); 145 | return 0; 146 | } 147 | -------------------------------------------------------------------------------- /DS/VirtualTree.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #define MAXV 100005 3 | #define INF 1000000000 4 | #define MAXLOGV 20 5 | using namespace std; 6 | struct edge 7 | { 8 | int to,cost; 9 | }; 10 | vector G[MAXV]; 11 | vector vt[MAXV]; 12 | int parent[MAXLOGV][MAXV]; 13 | int depth[MAXV],dfn[MAXV],dis[MAXV],st[MAXV]; 14 | int n,q,tot; 15 | void add_edge(int from,int to) 16 | { 17 | vt[from].push_back(to); 18 | } 19 | bool cmp(int x,int y) 20 | { 21 | return dfn[x]depth[v]) swap(u,v); 47 | for(int k=0;k>k&1) 50 | v=parent[k][v]; 51 | } 52 | if(u==v) return u; 53 | for(int k=MAXLOGV-1;k>=0;k--) 54 | { 55 | if(parent[k][u]!=parent[k][v]) 56 | { 57 | u=parent[k][u]; 58 | v=parent[k][v]; 59 | } 60 | } 61 | return parent[0][u]; 62 | } 63 | int build_vtree(vector &a) 64 | { 65 | sort(a.begin(),a.end(),cmp); 66 | a.erase(unique(a.begin(),a.end()),a.end()); 67 | assert(a.size()>0); 68 | int t=0; 69 | st[t++]=a[0]; 70 | vector newly;newly.clear(); 71 | for(int i=1;i<(int)a.size();i++) 72 | { 73 | if(t==0) {st[t++]=a[i]; continue;} 74 | int l=lca(a[i],st[t-1]); 75 | while(t>1&&dfn[st[t-2]]>=dfn[l]) add_edge(st[t-2],st[t-1]),t--; 76 | if(l!=st[t-1]) {add_edge(l,st[t-1]),st[t-1]=l; newly.push_back(l);} 77 | st[t++]=a[i]; 78 | } 79 | while(t>1) add_edge(st[t-2],st[t-1]),t--; 80 | for(auto it:newly) a.push_back(it); 81 | return st[0]; 82 | } 83 | int main() 84 | { 85 | return 0; 86 | } 87 | -------------------------------------------------------------------------------- /DS/Young Tableaux.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #define MAXN 5005 3 | #define MAXM 305 4 | #define INF 1000000000 5 | #define MOD 1000000007 6 | #define F first 7 | #define S second 8 | using namespace std; 9 | typedef long long ll; 10 | typedef pair P; 11 | int n,a[MAXN]; 12 | int t[MAXN]; 13 | int young[MAXM][MAXM]; 14 | void ins(int v) 15 | { 16 | for(int i=1;;i++) 17 | { 18 | if(t[i]==0||v>=young[i][t[i]]) 19 | { 20 | young[i][++t[i]]=v; 21 | break; 22 | } 23 | int pos=upper_bound(young[i]+1,young[i]+t[i]+1,v)-young[i]; 24 | swap(young[i][pos],v); 25 | } 26 | } 27 | int main() 28 | { 29 | scanf("%d",&n); 30 | for(int i=1;i<=n;i++) 31 | { 32 | scanf("%d",&a[i]); 33 | ins(a[i]); 34 | } 35 | int x=0; 36 | for(int i=1;;i++) 37 | { 38 | x+=t[i]; 39 | printf("%d\n",x); 40 | if(x==n) break; 41 | } 42 | return 0; 43 | } 44 | -------------------------------------------------------------------------------- /Geometry/ConvexHull.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include 8 | #define MAXN 50005 9 | using namespace std; 10 | double EPS= 1e-10; 11 | double add(double a,double b) 12 | { 13 | if(abs(a+b) convex_hull(P* ps,int n) 48 | { 49 | sort(ps,ps+n,cmp_x); 50 | int k=0; 51 | vector

qs(n*2); 52 | for(int i=0;i1&&(qs[k-1]-qs[k-2]).det(ps[i]-qs[k-1])<=0) k--; 55 | qs[k++]=ps[i]; 56 | } 57 | for(int i=n-2,t=k;i>=0;i--) 58 | { 59 | while(k>t&&(qs[k-1]-qs[k-2]).det(ps[i]-qs[k-1])<=0) k--; 60 | qs[k++]=ps[i]; 61 | } 62 | qs.resize(k-1); 63 | return qs; 64 | } 65 | double dist (P p,P q) 66 | { 67 | return (p-q).dot(p-q); 68 | } 69 | int N; 70 | P ps[MAXN]; 71 | int main() 72 | { 73 | scanf("%d",&N); 74 | for(int i=0;i qs=convex_hull(ps,N); 77 | double res=0; 78 | for(int i=0;i 2 | #define MAXV 3005 3 | #define MAXE 50000 4 | #define INF 1000000 5 | using namespace std; 6 | struct edge{int to,cap,rev;}; 7 | int V; 8 | vector G[MAXV]; 9 | int level[MAXV]; 10 | int iter[MAXV]; 11 | void add_edge(int from,int to,int cap) 12 | { 13 | G[from].push_back((edge){to,cap,(int)G[to].size()}); 14 | G[to].push_back((edge){from,0,(int)G[from].size()-1}); 15 | } 16 | void bfs(int s) 17 | { 18 | memset(level,-1,sizeof(level)); 19 | queue que; 20 | level[s]=0; 21 | que.push(s); 22 | while(!que.empty()) 23 | { 24 | int v=que.front(); que.pop(); 25 | for(int i=0;i<(int)G[v].size();i++) 26 | { 27 | edge &e=G[v][i]; 28 | if(e.cap>0&&level[e.to]<0) 29 | { 30 | level[e.to]=level[v]+1; 31 | que.push(e.to); 32 | } 33 | } 34 | } 35 | } 36 | 37 | int dfs(int v,int t,int f) 38 | { 39 | if(v==t) return f; 40 | for(int &i=iter[v];i<(int)G[v].size();i++) 41 | { 42 | edge &e=G[v][i]; 43 | if(level[v]0) 44 | { 45 | int d=dfs(e.to,t,min(f,e.cap)); 46 | if(d>0) 47 | { 48 | e.cap-=d; 49 | G[e.to][e.rev].cap+=d; 50 | return d; 51 | } 52 | } 53 | } 54 | return 0; 55 | } 56 | int max_flow(int s,int t) 57 | { 58 | int flow=0; 59 | for(;;) 60 | { 61 | bfs(s); 62 | if(level[t]<0) return flow; 63 | memset(iter,0,sizeof(iter)); 64 | int f; 65 | while((f=dfs(s,t,INF))>0) 66 | flow+=f; 67 | } 68 | } 69 | -------------------------------------------------------------------------------- /Graph/Flow and cut algorithms/FordFulkerson.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #define MAXV 1000 3 | #define MAXE 10000 4 | #define INF 1000000 5 | using namespace std; 6 | struct edge{int to,cap,rev;}; 7 | bool used[MAXV]; 8 | int V; 9 | vector G[MAXV]; 10 | void add_edge(int from,int to,int cap) 11 | { 12 | G[from].push_back((edge){to,cap,G[to].size()}); 13 | G[to].push_back((edge){from,0,G[from].size()-1}); 14 | } 15 | int dfs(int v,int t,int f) 16 | { 17 | if(v==t) return f; 18 | used[v]=true; 19 | for(int i=0;i0) 23 | { 24 | int d=dfs(e.to,t,min(f,e.cap)); 25 | if(d>0) 26 | { 27 | e.cap-=d; 28 | G[e.to][e.rev].cap+=d; 29 | return d; 30 | } 31 | } 32 | } 33 | return 0; 34 | } 35 | int max_flow(int s,int t) 36 | { 37 | int flow=0; 38 | for(;;) 39 | { 40 | memset(used,0,sizeof(used)); 41 | int f=dfs(s,t,INF); 42 | if(f==0) return flow; 43 | flow+=f; 44 | } 45 | } 46 | int main() 47 | { 48 | return 0; 49 | } 50 | -------------------------------------------------------------------------------- /Graph/Flow and cut algorithms/GomoryHuTree.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #define MAXV 3005 3 | #define MAXE 50000 4 | #define INF 1000000000 5 | using namespace std; 6 | typedef pair P; 7 | typedef long long ll; 8 | struct edge{int to,cap,rev,id;};//id=1 positive edge, id=0 reverse edge 9 | struct edge2{int to,cost;}; 10 | struct edge3{int from,to,cap;}; 11 | int V,E; 12 | vector G[MAXV]; 13 | vector gh[MAXV]; 14 | vector edges; 15 | int level[MAXV]; 16 | int iter[MAXV]; 17 | void add_edge(int from,int to,int cap) 18 | { 19 | edges.push_back((edge3){from,to,cap}); 20 | } 21 | void add_all() 22 | { 23 | for(auto e:edges) 24 | { 25 | G[e.from].push_back((edge){e.to,e.cap,(int)G[e.to].size(),1}); 26 | G[e.to].push_back((edge){e.from,0,(int)G[e.from].size()-1,0}); 27 | } 28 | } 29 | void clear_all() 30 | { 31 | for(int i=1;i<=V;i++) G[i].clear(); 32 | } 33 | void bfs(int s) 34 | { 35 | memset(level,-1,sizeof(level)); 36 | queue que; 37 | level[s]=0; 38 | que.push(s); 39 | while(!que.empty()) 40 | { 41 | int v=que.front(); que.pop(); 42 | for(int i=0;i<(int)G[v].size();i++) 43 | { 44 | edge &e=G[v][i]; 45 | if(e.cap>0&&level[e.to]<0) 46 | { 47 | level[e.to]=level[v]+1; 48 | que.push(e.to); 49 | } 50 | } 51 | } 52 | } 53 | 54 | int dfs(int v,int t,int f) 55 | { 56 | if(v==t) return f; 57 | for(int &i=iter[v];i<(int)G[v].size();i++) 58 | { 59 | edge &e=G[v][i]; 60 | if(level[v]0) 61 | { 62 | int d=dfs(e.to,t,min(f,e.cap)); 63 | if(d>0) 64 | { 65 | e.cap-=d; 66 | G[e.to][e.rev].cap+=d; 67 | return d; 68 | } 69 | } 70 | } 71 | return 0; 72 | } 73 | int max_flow(int s,int t) 74 | { 75 | int flow=0; 76 | for(;;) 77 | { 78 | bfs(s); 79 | if(level[t]<0) return flow; 80 | memset(iter,0,sizeof(iter)); 81 | int f; 82 | while((f=dfs(s,t,INF))>0) 83 | flow+=f; 84 | } 85 | } 86 | //0-based!!! 87 | void build_gomory_hu_tree() 88 | { 89 | vector p(V+1,1),cap(V+1,0); 90 | for(int s=2;s<=V;s++) 91 | { 92 | add_all(); 93 | int t=p[s]; 94 | cap[s]=max_flow(s,t); 95 | vector in_cut(V+1,0); 96 | queue que({s}); 97 | in_cut[s]=true; 98 | while(!que.empty()) 99 | { 100 | int v=que.front(); 101 | que.pop(); 102 | for(auto e:G[v]) 103 | { 104 | if(e.cap>0&&!in_cut[e.to]) 105 | { 106 | in_cut[e.to]=true; 107 | que.push(e.to); 108 | } 109 | } 110 | } 111 | for(int v=1;v<=V;v++) 112 | if(v!=s&&in_cut[v]&&p[v]==t) 113 | p[v]=s; 114 | if(in_cut[p[t]]) 115 | { 116 | p[s]=p[t]; 117 | p[t]=s; 118 | swap(cap[s],cap[t]); 119 | } 120 | clear_all(); 121 | } 122 | for(int v=2;v<=V;v++) 123 | { 124 | gh[p[v]].push_back((edge2){v,cap[v]}); 125 | gh[v].push_back((edge2){p[v],cap[v]}); 126 | } 127 | } 128 | int main() 129 | { 130 | scanf("%d%d",&V,&E); 131 | for(int i=0;i 2 | #define MAXV 500005 3 | #define MAXE 1000005 4 | #define INF 1000000000000000000LL 5 | using namespace std; 6 | typedef long long ll; 7 | typedef pair P; 8 | struct edge{int to,cap; ll cost; int rev;}; 9 | int n,m,V,s[MAXV],e[MAXV]; 10 | ll w[MAXV]; 11 | ll h[MAXV],dist[MAXV]; 12 | int prevv[MAXV],preve[MAXV]; 13 | vector G[MAXV]; 14 | bool inque[MAXV]; 15 | void add_edge(int from,int to,int cap,ll cost) 16 | { 17 | G[from].push_back((edge){to,cap,cost,(int)G[to].size()}); 18 | G[to].push_back((edge){from,0,-cost,(int)G[from].size()-1}); 19 | } 20 | void dijkstra(int s) 21 | { 22 | priority_queue,greater

>que; 23 | fill(dist+1,dist+V+1,INF); 24 | dist[s]=0; 25 | que.push(P(0,s)); 26 | while(!que.empty()) 27 | { 28 | P p=que.top(); que.pop(); 29 | int v=p.second; 30 | if(dist[v]0&&dist[e.to]>dist[v]+e.cost+h[v]-h[e.to]) 35 | { 36 | dist[e.to]=dist[v]+e.cost+h[v]-h[e.to]; 37 | prevv[e.to]=v; 38 | preve[e.to]=i; 39 | que.push(P(dist[e.to],e.to)); 40 | } 41 | } 42 | } 43 | } 44 | void spfa(int s) 45 | { 46 | queueque; 47 | fill(h+1,h+V+1,INF); 48 | fill(inque+1,inque+V+1,false); 49 | h[s]=0; 50 | que.push(s); 51 | while(!que.empty()) 52 | { 53 | int u=que.front(); que.pop(); 54 | for(int i=0;i<(int)G[u].size();i++) 55 | { 56 | if(G[u][i].cap>0&&h[u]+G[u][i].cost=0) return res; 80 | for(int v=1;v<=V;v++) h[v]+=dist[v]; 81 | int d=V; 82 | for(int v=t;v!=s;v=prevv[v]) 83 | { 84 | d=min(d,G[prevv[v]][preve[v]].cap); 85 | } 86 | res+=d*h[t]; 87 | for(int v=t;v!=s;v=prevv[v]) 88 | { 89 | edge &e=G[prevv[v]][preve[v]]; 90 | e.cap-=d; 91 | G[v][e.rev].cap+=d; 92 | } 93 | } 94 | } 95 | -------------------------------------------------------------------------------- /Graph/Flow and cut algorithms/MinCostFlow.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #define MAXV 1000 3 | #define MAXE 10000 4 | #define INF 1000000 5 | using namespace std; 6 | typedef pair P; 7 | struct edge{int to,cap,cost,rev;}; 8 | int dist[MAXV],h[MAXV],prevv[MAXV],preve[MAXV]; 9 | int V; 10 | vector G[MAXV]; 11 | void add_edge(int from,int to,int cap,int cost) 12 | { 13 | G[from].push_back((edge){to,cap,cost,(int)G[to].size()}); 14 | G[to].push_back((edge){from,0,-cost,(int)G[from].size()-1}); 15 | } 16 | int min_cost_flow(int s,int t,int f) 17 | { 18 | int res=0; 19 | fill(h+1,h+V+1,0); 20 | while(f>0) 21 | { 22 | priority_queue,greater

>que; 23 | fill(dist+1,dist+V+1,INF); 24 | dist[s]=0; 25 | que.push(P(0,s)); 26 | while(!que.empty()) 27 | { 28 | P p=que.top(); que.pop(); 29 | int v=p.second; 30 | if(dist[v]0&&dist[e.to]>dist[v]+e.cost+h[v]-h[e.to]) 35 | { 36 | dist[e.to]=dist[v]+e.cost+h[v]-h[e.to]; 37 | prevv[e.to]=v; 38 | preve[e.to]=i; 39 | que.push(P(dist[e.to],e.to)); 40 | } 41 | } 42 | } 43 | if(dist[t]==INF) 44 | { 45 | return -1; 46 | } 47 | for(int v=1;v<=V;v++) h[v]+=dist[v]; 48 | int d=f; 49 | for(int v=t;v!=s;v=prevv[v]) 50 | { 51 | d=min(d,G[prevv[v]][preve[v]].cap); 52 | } 53 | f-=d; 54 | res+=d*h[t]; 55 | for(int v=t;v!=s;v=prevv[v]) 56 | { 57 | edge &e=G[prevv[v]][preve[v]]; 58 | e.cap-=d; 59 | G[v][e.rev].cap+=d; 60 | } 61 | } 62 | return res; 63 | } 64 | int main() 65 | { 66 | return 0; 67 | } 68 | -------------------------------------------------------------------------------- /Graph/Matching algorithms/BipartiteMatching.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #define MAXN 10005 3 | using namespace std; 4 | int V; 5 | vector G[MAXN]; 6 | int match[MAXN]; 7 | bool used[MAXN]; 8 | void add_edge(int u,int v) 9 | { 10 | G[u].push_back(v); 11 | G[v].push_back(u); 12 | } 13 | bool dfs(int v) 14 | { 15 | used[v]=true; 16 | for(int i=0;i 2 | #define MAXN 500 3 | int n,m,x,y,fore,rear,cnt,ans,father[MAXN],f[MAXN],path[MAXN],tra[MAXN],que[MAXN],match[MAXN]; 4 | bool a[MAXN][MAXN],check[MAXN],treec[MAXN],pathc[MAXN]; 5 | inline void push(int x) 6 | { 7 | que[++rear]=x; 8 | check[x]=true; 9 | if(!treec[x]) 10 | { 11 | tra[++cnt]=x; 12 | treec[x]=true; 13 | } 14 | } 15 | int root(int x){return f[x]?f[x]=root(f[x]):x;} 16 | 17 | void clear() 18 | { 19 | for(int i=1,j;i<=cnt;++i) 20 | { 21 | j=tra[i]; 22 | check[j]=treec[j]=false; 23 | father[j]=0,f[j]=0; 24 | } 25 | } 26 | 27 | int lca(int u,int v) 28 | { 29 | int len=0; 30 | for(;u;u=father[match[u]]) 31 | { 32 | u=root(u); 33 | path[++len]=u; 34 | pathc[u]=true; 35 | } 36 | for(;;v=father[match[v]]) 37 | { 38 | v=root(v); 39 | if(pathc[v]) break; 40 | } 41 | for(int i=1;i<=len;++i) 42 | { 43 | pathc[path[i]]=false; 44 | } 45 | return v; 46 | } 47 | 48 | void reset(int u,int p) 49 | { 50 | for(int v;root(u)!=p;) 51 | { 52 | if(!check[v=match[u]]) push(v); 53 | if(f[u]==0) f[u]=p; 54 | if(f[v]==0) f[v]=p; 55 | u=father[v]; 56 | if(root(u)!=p) father[u]=v; 57 | } 58 | } 59 | 60 | void flower(int u,int v) 61 | { 62 | int p=lca(u,v); 63 | if(root(u)!=p) father[u]=v; 64 | if(root(v)!=p) father[v]=u; 65 | reset(u,p),reset(v,p); 66 | } 67 | 68 | bool find(int x) 69 | { 70 | fore=rear=cnt=0,push(x); 71 | while(fore++ 2 | #define MAXN 50030 3 | using namespace std; 4 | int n1,n2; 5 | vector G[MAXN]; 6 | int mx[MAXN],my[MAXN]; 7 | queue que; 8 | int dx[MAXN],dy[MAXN]; 9 | bool vis[MAXN]; 10 | bool find(int u) 11 | { 12 | for(int i=0;i 3 | #define MAXN 1005 4 | #define INF 1000000000 5 | #define MOD 1000000007 6 | #define F first 7 | #define S second 8 | using namespace std; 9 | typedef long long ll; 10 | typedef pair P; 11 | int n; 12 | int w[MAXN][MAXN]; 13 | //minimum weight bipartite matching 14 | ll km(int n,int m) 15 | { 16 | vector u(n+1),v(m+1),p(m+1),way(m+1); 17 | for(int i=1;i<=n;i++) 18 | { 19 | p[0]=i; 20 | int j0=0; 21 | vector minv(m+1,INF); 22 | vector used(m+1,false); 23 | do 24 | { 25 | used[j0]=true; 26 | int i0=p[j0],delta=INF,j1; 27 | for(int j=1;j<=m;++j) 28 | if(!used[j]) 29 | { 30 | int cur=w[i0][j]-u[i0]-v[j]; 31 | if(cur 2 | #define MAXV 10000 3 | #define MAXE 1000 4 | #define INF 1000000 5 | #define MAXN 100000 6 | using namespace std; 7 | struct edge{int u,v,cost;}; 8 | bool cmp(const edge &e1,const edge &e2) 9 | { 10 | return e1.cost 2 | #define MAXV 100005 3 | #define MAXE 300005 4 | #define INF 1000000000 5 | using namespace std; 6 | typedef pair P; 7 | int V,E; 8 | struct edge 9 | { 10 | int to,cost; 11 | }; 12 | vector G[MAXV];// adjacency table 13 | priority_queue, greater

> pq; //priority queue(defaulted to extract the minimum) 14 | bool used[MAXV];// to judge if some vertex is in the MST 15 | int dis[MAXV];//minimum distance to vertex i 16 | int prim() 17 | { 18 | int ans=0; 19 | memset(used,false,sizeof(used)); 20 | fill(dis,dis+V,INF); 21 | dis[0]=0; 22 | while(!pq.empty()) pq.pop(); 23 | pq.push(P(0,0)); 24 | while(!pq.empty()) 25 | { 26 | P p=pq.top();pq.pop(); 27 | int v=p.second; 28 | if(used[v]||p.first>dis[v]) continue; 29 | used[v]=true; 30 | ans+=dis[v]; 31 | for(int i=0;ie.cost) 35 | { 36 | dis[e.to]=e.cost; 37 | pq.push(P(dis[e.to],e.to)); 38 | } 39 | } 40 | } 41 | return ans; 42 | } 43 | int main() 44 | { 45 | scanf("%d%d",&V,&E); 46 | for(int i=0;i 2 | #define MAXV 1000 3 | #define MAXE 10000 4 | #define INF 1000000 5 | using namespace std; 6 | int cost[MAXV][MAXV]; 7 | int mincost[MAXV]; 8 | bool used[MAXV]; 9 | int V; 10 | int prim() 11 | { 12 | for(int i=0;i 2 | #define MAXN 2005 3 | #define MAXM 100005 4 | #define INF 100000000 5 | #define MOD 100000007 6 | #define F first 7 | #define S second 8 | using namespace std; 9 | typedef long long ll; 10 | typedef pair P; 11 | int a,b,n,m,d; 12 | int deg[MAXN]; 13 | P to[MAXN][MAXN]; 14 | int c[MAXM]; 15 | P e[MAXM]; 16 | void recolor(int u,int c1,int c2) 17 | { 18 | int v=to[u][c1].F; 19 | int id=to[u][c1].S; 20 | to[v][c1]=to[u][c1]=P(0,0); 21 | c[id]=c2; 22 | to[u][c2]=P(v,id); 23 | if(to[v][c2].F==0) 24 | { 25 | to[v][c2]=P(u,id); 26 | return; 27 | } 28 | recolor(v,c2,c1); 29 | to[v][c2]=P(u,id); 30 | } 31 | void color(int id) 32 | { 33 | int u=e[id].F,v=e[id].S; 34 | for(int i=1;i<=d;i++) 35 | { 36 | if(!to[u][i].F&&!to[v][i].F) 37 | { 38 | c[id]=i; 39 | to[u][i]=P(v,id); 40 | to[v][i]=P(u,id); 41 | return; 42 | } 43 | } 44 | int x=-1,y=-1; 45 | for(int i=1;i<=d;i++) 46 | { 47 | if(!to[u][i].F) x=i; 48 | if(!to[v][i].F) y=i; 49 | } 50 | assert(x!=-1&&y!=-1); 51 | c[id]=x; 52 | to[u][x]=P(v,id); 53 | recolor(v,x,y); 54 | to[v][x]=P(u,id); 55 | } 56 | int main() 57 | { 58 | scanf("%d%d%d",&a,&b,&m); 59 | n=a+b; 60 | for(int i=1;i<=m;i++) 61 | { 62 | scanf("%d%d",&e[i].F,&e[i].S); 63 | e[i].S+=a; 64 | deg[e[i].F]++; deg[e[i].S]++; 65 | } 66 | d=0; 67 | for(int i=1;i<=n;i++) d=max(d,deg[i]); 68 | printf("%d\n",d); 69 | for(int i=1;i<=m;i++) color(i); 70 | for(int i=1;i<=m;i++) printf("%d ",c[i]); 71 | puts(""); 72 | return 0; 73 | } -------------------------------------------------------------------------------- /Graph/Others/BlockCutTree.cpp: -------------------------------------------------------------------------------- 1 | #pragma GCC optimize(3) 2 | #include 3 | #define MAXN 100005 4 | #define MAXM 100005 5 | #define INF 1000000000 6 | #define MOD 1000000007 7 | #define F first 8 | #define S second 9 | using namespace std; 10 | typedef long long ll; 11 | typedef pair P; 12 | int n,m,tot,t,bcc_cnt,mcnt; 13 | vector G[MAXN],bcc[MAXN]; 14 | int st[MAXN],dfn[MAXN],low[MAXN],bccno[MAXN]; 15 | bool art[MAXN]; 16 | vector tree[MAXN]; 17 | int id[MAXN]; 18 | int N; 19 | //block-cut tree: 20 | //vertex-biconnected components are connected by their shared articulation point 21 | void dfs(int v,int p,int &tot) 22 | { 23 | dfn[v]=low[v]=++tot; 24 | st[t++]=v; 25 | for(auto to:G[v]) 26 | { 27 | if(to==p) continue; 28 | if(!dfn[to]) 29 | { 30 | dfs(to,v,tot); 31 | low[v]=min(low[v],low[to]); 32 | if(low[to]>=dfn[v]) 33 | { 34 | art[v]=(dfn[v]>1||dfn[to]>2); 35 | bcc_cnt++; 36 | bcc[bcc_cnt].push_back(v); bccno[v]=bcc_cnt; 37 | while(bcc[bcc_cnt].back()!=to) 38 | { 39 | bccno[st[t-1]]=bcc_cnt; 40 | bcc[bcc_cnt].push_back(st[t-1]),t--; 41 | } 42 | } 43 | } 44 | else low[v]=min(low[v],dfn[to]); 45 | } 46 | } 47 | int tarjan() 48 | { 49 | bcc_cnt=t=0; 50 | memset(dfn,0,sizeof(dfn)); 51 | memset(art,false,sizeof(art)); 52 | for(int i=1;i<=n;i++) if(!dfn[i]) dfs(i,-1,tot=0); 53 | return bcc_cnt; 54 | } 55 | void build_block_cut_tree() 56 | { 57 | tarjan();N=0; 58 | for(int i=1;i<=n;i++) if(art[i]) id[i]=++N; 59 | for(int i=1;i<=bcc_cnt;i++) 60 | { 61 | N++; 62 | for(auto v:bcc[i]) 63 | { 64 | if(!art[v]) id[v]=N; 65 | else 66 | { 67 | tree[id[v]].push_back(N); 68 | tree[N].push_back(id[v]); 69 | } 70 | } 71 | } 72 | } 73 | 74 | -------------------------------------------------------------------------------- /Graph/Others/BridgeTree.cpp: -------------------------------------------------------------------------------- 1 | #pragma GCC optimize(3) 2 | #include 3 | #define MAXN 100005 4 | #define MAXM 100005 5 | #define INF 1000000000 6 | #define MOD 1000000007 7 | #define F first 8 | #define S second 9 | using namespace std; 10 | typedef long long ll; 11 | typedef pair P; 12 | int n,m,tot,t,bcc_cnt,mcnt; 13 | vector G[MAXN],bcc[MAXN]; 14 | int st[MAXN],dfn[MAXN],low[MAXN],bccno[MAXN]; 15 | int U[MAXM],V[MAXM]; 16 | bool isbridge[MAXM]; 17 | vector tree[MAXN]; 18 | //bridge tree: 19 | //edge-biconnected components are connected by bridges 20 | void add_edge(int u,int v) 21 | { 22 | U[++mcnt]=u;V[mcnt]=v; 23 | G[u].push_back(mcnt);G[v].push_back(mcnt); 24 | } 25 | int adj(int u,int e) 26 | { 27 | return U[e]==u?V[e]:U[e]; 28 | } 29 | void dfs1(int v,int edge) 30 | { 31 | dfn[v]=low[v]=++tot; 32 | st[t++]=v; 33 | for(auto e:G[v]) 34 | { 35 | if(e==edge) continue; 36 | int to=adj(v,e); 37 | if(!dfn[to]) 38 | { 39 | dfs1(to,e); 40 | low[v]=min(low[v],low[to]); 41 | } 42 | else low[v]=min(low[v],dfn[to]); 43 | } 44 | if(low[v]==dfn[v]&&edge!=-1) isbridge[edge]=true; 45 | } 46 | void dfs2(int v) 47 | { 48 | dfn[v]=1; 49 | bccno[v]=bcc_cnt; 50 | bcc[bcc_cnt].push_back(v); 51 | for(auto e:G[v]) 52 | { 53 | int to=adj(v,e); 54 | if(isbridge[e]) continue; 55 | if(!dfn[to]) dfs2(to); 56 | } 57 | } 58 | int tarjan() 59 | { 60 | bcc_cnt=tot=0; 61 | memset(dfn,0,sizeof(dfn)); 62 | memset(isbridge,false,sizeof(isbridge)); 63 | for(int i=1;i<=n;i++) if(!dfn[i]) dfs1(i,-1); 64 | memset(dfn,0,sizeof(dfn)); 65 | for(int i=1;i<=n;i++) 66 | { 67 | if(!dfn[i]) 68 | { 69 | bcc_cnt++; 70 | dfs2(i); 71 | } 72 | } 73 | return bcc_cnt; 74 | } 75 | void build_bridge_tree() 76 | { 77 | tarjan(); 78 | for(int i=1;i<=mcnt;i++) 79 | { 80 | if(isbridge[i]) 81 | { 82 | int u=bccno[U[i]],v=bccno[V[i]]; 83 | tree[u].push_back(v);tree[v].push_back(u); 84 | } 85 | } 86 | } 87 | 88 | -------------------------------------------------------------------------------- /Graph/Others/ChordalGraph.cpp: -------------------------------------------------------------------------------- 1 | /************************************************************************* 2 | > File Name: ChordalGraph.cpp 3 | > Author: Roundgod 4 | > Mail: wcysai@foxmail.com 5 | > Created Time: 2018-10-31 15:49:59 6 | ************************************************************************/ 7 | 8 | #pragma GCC optimize(3) 9 | #include 10 | #define MAXN 100005 11 | #define INF 1000000000 12 | #define MOD 1000000007 13 | #define F first 14 | #define S second 15 | using namespace std; 16 | typedef long long ll; 17 | typedef pair P; 18 | int n,m; 19 | vector G[MAXN]; 20 | int h[MAXN],label[MAXN]; 21 | vector st[MAXN]; 22 | bool vis[MAXN]; 23 | vector peo; 24 | void MCS() 25 | { 26 | memset(vis,0,sizeof(vis)); 27 | memset(h,0,sizeof(h)); 28 | int cur=0; 29 | for(int i=1;i<=n;i++) st[0].push_back(i); 30 | for(int i=n;i>=1;i--) 31 | { 32 | while(1) 33 | { 34 | while(st[cur].size()==0) cur--; 35 | int now=st[cur].back(); 36 | st[cur].pop_back();if(vis[now]) continue; 37 | vis[now]=true;label[now]=i; 38 | for(auto to:G[now]) 39 | { 40 | if(vis[to]) continue; 41 | h[to]++; st[h[to]].push_back(to); cur=max(cur,h[to]); 42 | } 43 | break; 44 | } 45 | } 46 | reverse(peo.begin(),peo.end()); 47 | } 48 | 49 | -------------------------------------------------------------------------------- /Graph/Others/DominatorTree.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #define MAXN 100005 3 | #define INF 1000000000 4 | #define MOD 1000000007 5 | #define F first 6 | #define S second 7 | using namespace std; 8 | typedef long long ll; 9 | typedef pair P; 10 | vector G[MAXN],rG[MAXN],dt[MAXN],bucket[MAXN]; 11 | int sdom[MAXN],idom[MAXN],arr[MAXN],rev[MAXN],par[MAXN],dsu[MAXN],label[MAXN]; 12 | int n,m,t; 13 | int find(int u,int x=0) 14 | { 15 | if(u==dsu[u]) return x?-1:u; 16 | int v=find(dsu[u],x+1); 17 | if(v<0) return u; 18 | if(sdom[label[dsu[u]]]=1;i--) 42 | { 43 | for(int j=0;j<(int)rG[i].size();j++) 44 | sdom[i]=min(sdom[i],sdom[find(rG[i][j])]); 45 | if(i>1) bucket[sdom[i]].push_back(i); 46 | for(int j=0;j<(int)bucket[i].size();j++) 47 | { 48 | int w=bucket[i][j],v=find(w); 49 | if(sdom[v]==sdom[w]) idom[w]=sdom[w]; 50 | else idom[w]=v; 51 | } 52 | if(i>1) unite(par[i],i); 53 | } 54 | for(int i=2;i<=N;i++) 55 | { 56 | if(idom[i]!=sdom[i]) idom[i]=idom[idom[i]]; 57 | dt[rev[idom[i]]].push_back(rev[i]); 58 | } 59 | for(int i=1;i<=N;i++) bucket[i].clear(),rG[i].clear(); 60 | } 61 | 62 | -------------------------------------------------------------------------------- /Graph/Others/DynamicConnectivity.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #define MAXN 300005 3 | #define INF 1000000000 4 | #define MOD 1000000007 5 | #define F first 6 | #define S second 7 | using namespace std; 8 | typedef long long ll; 9 | typedef pair P; 10 | int n,k,x,y; 11 | char str[2]; 12 | vector

edges[4*MAXN]; 13 | bool ask[MAXN]; 14 | int p[MAXN],r[MAXN],sz[MAXN]; 15 | int ans[MAXN]; 16 | int num; 17 | struct update 18 | { 19 | int x,y; 20 | bool addrk; 21 | }; 22 | update st[MAXN]; 23 | int t; 24 | void init(int n) 25 | { 26 | for(int i=1;i<=n;i++) 27 | { 28 | p[i]=i; 29 | r[i]=0; 30 | } 31 | } 32 | int find(int x) 33 | { 34 | while(p[x]!=x) x=p[x]; 35 | return x; 36 | } 37 | bool unite(int x,int y) 38 | { 39 | x=find(x); 40 | y=find(y); 41 | if(x==y) return false; 42 | num--; 43 | if(r[x]r||l>y) return; 72 | if(l>=x&&r<=y) 73 | { 74 | edges[k].push_back(P(u,v)); 75 | return; 76 | } 77 | int mid=(l+r)/2; 78 | add_edge(k*2,l,mid,x,y,u,v);add_edge(k*2+1,mid+1,r,x,y,u,v); 79 | } 80 | void solve(int k,int l,int r) 81 | { 82 | if(l>r) return; 83 | int cnt=0; 84 | for(auto e:edges[k]) if(unite(e.F,e.S)) cnt++; 85 | if(l==r) 86 | { 87 | if(ask[l]) ans[l]=num; 88 | for(int i=0;i mp; 97 | int main() 98 | { 99 | scanf("%d%d",&n,&k);num=n;init(n); 100 | memset(ask,false,sizeof(ask)); 101 | for(int i=1;i<=k;i++) 102 | { 103 | scanf("%s",str); 104 | if(str[0]=='?') 105 | { 106 | ask[i]=true; 107 | continue; 108 | } 109 | scanf("%d%d",&x,&y); 110 | if(x>y) swap(x,y); 111 | if(str[0]=='+') mp[P(x,y)]=i; 112 | else 113 | { 114 | add_edge(1,1,k,mp[P(x,y)],i-1,x,y); 115 | mp[P(x,y)]=-1; 116 | } 117 | } 118 | for(auto p:mp) if(p.S!=-1) add_edge(1,1,k,p.S,k,p.F.F,p.F.S); 119 | solve(1,1,k); 120 | for(int i=1;i<=k;i++) if(ask[i]) printf("%d\n",ans[i]); 121 | return 0; 122 | } 123 | 124 | -------------------------------------------------------------------------------- /Graph/Others/EarDecomposition.cpp: -------------------------------------------------------------------------------- 1 | #pragma GCC optimize(3) 2 | #include 3 | #include 4 | #include 5 | #include 6 | #define MAXN 100005 7 | #define INF 1000000000 8 | #define MOD 1000000007 9 | #define F first 10 | #define S second 11 | using namespace std; 12 | using namespace __gnu_pbds; 13 | typedef long long ll; 14 | typedef pair P; 15 | typedef tree,rb_tree_tag,tree_order_statistics_node_update> ordered_set; 16 | typedef __gnu_pbds::priority_queue,pairing_heap_tag> pq; 17 | int n,m; 18 | vector G[MAXN]; 19 | int dep[MAXN]; 20 | vector > ears; 21 | vector path[MAXN]; 22 | vector back[MAXN]; 23 | int low[MAXN]; 24 | int vis[MAXN]; 25 | bool f=true; 26 | void cmin(int &a,int b) 27 | { 28 | if(dep[b] &a) 31 | { 32 | reverse(a.begin(),a.end()); 33 | a.push_back(to); 34 | ears.push_back(a); 35 | } 36 | void dfs(int v,int p,int d) 37 | { 38 | if(!f) return; 39 | vis[v]=1;dep[v]=d;low[v]=v; 40 | int used=0; 41 | for(auto to:G[v]) 42 | { 43 | if(to==p) continue; 44 | if(!vis[to]) 45 | { 46 | dfs(to,v,d+1); 47 | path[to].push_back(v); 48 | if(!used||dep[low[to]]){v,u}); 71 | } 72 | /* printf("%d %d %d\n",v,dep[v],low[v]); 73 | printf("chain %d\n",v); 74 | for(auto x:path[v]) printf("%d ",x); 75 | puts(""); */ 76 | if(dep[low[v]]==dep[v]&&v!=1) f=false; 77 | } 78 | int main() 79 | { 80 | scanf("%d%d",&n,&m); 81 | for(int i=0;i res; 7 | int now[MAXN]; 8 | void hierholzer(int v){//find an eulerian path starting from v, assuming connected 9 | while(now[v]<(int)G[v].size()){ 10 | auto &e=G[v][now[v]]; 11 | if(e.del) {now[v]++; continue;} 12 | e.del=1; G[e.to][e.rev].del=1; 13 | hierholzer(e.to); 14 | now[v]++; 15 | } 16 | res.push_back(v); 17 | } 18 | -------------------------------------------------------------------------------- /Graph/Others/Kosaraju.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #define MAXN 100005 3 | using namespace std; 4 | int n; 5 | vector G[MAXN]; 6 | vector rG[MAXN]; 7 | vector vs; 8 | bool used[MAXN]; 9 | int cmp[MAXN]; 10 | void add_edge(int from,int to) 11 | { 12 | G[from].push_back(to); 13 | rG[to].push_back(from); 14 | } 15 | void dfs(int v) 16 | { 17 | used[v]=true; 18 | for(int i=0;i<(int)G[v].size();i++) 19 | if(!used[G[v][i]]) dfs(G[v][i]); 20 | vs.push_back(v); 21 | } 22 | void rdfs(int v,int k) 23 | { 24 | used[v]=true; 25 | cmp[v]=k; 26 | for(int i=0;i<(int)rG[v].size();i++) 27 | if(!used[rG[v][i]]) rdfs(rG[v][i],k); 28 | } 29 | int scc() 30 | { 31 | memset(used,0,sizeof(used)); 32 | vs.clear(); 33 | for(int v=1;v<=n;v++) if(!used[v]) dfs(v); 34 | int k=0; 35 | memset(used,0,sizeof(used)); 36 | for(int i=vs.size()-1;i>=0;i--) if(!used[vs[i]]) rdfs(vs[i],k++); 37 | return k; 38 | } 39 | -------------------------------------------------------------------------------- /Graph/Others/LCA.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #define MAXN 100005 3 | #define MAXLOGN 20 4 | using namespace std; 5 | vector G[MAXN]; 6 | int pa[MAXLOGN][MAXN]; 7 | int depth[MAXN]; 8 | int n,q; 9 | void dfs(int v,int p,int d) 10 | { 11 | pa[0][v]=p; 12 | depth[v]=d; 13 | for(int i=0;i<(int)G[v].size();i++) 14 | if(G[v][i]!=p) dfs(G[v][i],v,d+1); 15 | } 16 | void init(int V) 17 | { 18 | dfs(1,-1,0); 19 | for(int k=0;k+1>k)&1) 32 | v=pa[k][v]; 33 | return v; 34 | } 35 | int lca(int u,int v) 36 | { 37 | if(depth[u]>depth[v]) swap(u,v); 38 | v=get(v,depth[v]-depth[u]); 39 | if(u==v) return u; 40 | for(int k=MAXLOGN-1;k>=0;k--) 41 | { 42 | if(pa[k][u]!=pa[k][v]) 43 | { 44 | u=pa[k][u]; 45 | v=pa[k][v]; 46 | } 47 | } 48 | return pa[0][u]; 49 | } 50 | int dis(int u,int v) 51 | { 52 | return depth[u]+depth[v]-2*depth[lca(u,v)]; 53 | } 54 | -------------------------------------------------------------------------------- /Graph/Others/LCArmq.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #define MAXN 100005 3 | #define MAXLOGN 22 4 | #define INF 1000000000 5 | #define MOD 1000000007 6 | #define F first 7 | #define S second 8 | using namespace std; 9 | typedef long long ll; 10 | typedef pair P; 11 | int n,q; 12 | int st[MAXLOGN+1][4*MAXN]; 13 | vector G[MAXN]; 14 | int vs[MAXN*2-1]; 15 | int depth[MAXN*2-1]; 16 | int id[MAXN]; 17 | void dfs(int v,int p,int d,int &k) 18 | { 19 | id[v]=k; 20 | vs[k]=v; 21 | depth[k++]=d; 22 | for(int i=0;i<(int)G[v].size();i++) 23 | { 24 | if(G[v][i]!=p) 25 | { 26 | dfs(G[v][i],v,d+1,k); 27 | vs[k]=v; 28 | depth[k++]=d; 29 | } 30 | } 31 | } 32 | int getMin(int x, int y) 33 | { 34 | return depth[x] 2 | #define MAXN 100005 3 | #define INF 1000000000 4 | #define MOD 1000000007 5 | #define F first 6 | #define S second 7 | using namespace std; 8 | typedef long long ll; 9 | typedef pair P; 10 | int n,k,a[MAXN]; 11 | namespace ZL 12 | { 13 | const int N=100010,M=100010,inf=1e9; 14 | struct edge 15 | { 16 | int u,v,w,use,id; 17 | }b[M],a[2000100]; 18 | int n,m,ans,pre[N],id[N],vis[N],root,In[N],h[N],len,way[M]; 19 | void init(int _n,int _root) 20 | { 21 | n=_n; m=0; b[0].w=inf; root=_root; ans=0; 22 | } 23 | void add(int u,int v,int w) 24 | { 25 | b[++m]=(edge){u,v,w,0,m}; 26 | a[m]=b[m]; 27 | } 28 | int work() 29 | { 30 | len=m; 31 | for (;;) 32 | { 33 | for (int i=1;i<=n;i++){pre[i]=0; In[i]=inf; id[i]=0; vis[i]=0; h[i]=0;} 34 | for (int i=1;i<=m;i++) 35 | if (b[i].u!=b[i].v&&b[i].wm;i--) 80 | { 81 | a[a[i].u].use+=a[i].use; a[a[i].v].use-=a[i].use; 82 | } 83 | for (int i=1;i<=m;i++) way[i]=a[i].use; 84 | } 85 | } 86 | -------------------------------------------------------------------------------- /Graph/Others/MinimumDiameterSpanningTree.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #define MAXN 505 3 | #define MAXM 200005 4 | #define INF 1000000000000000000LL 5 | #define MOD 1000000007 6 | #define F first 7 | #define S second 8 | using namespace std; 9 | typedef long long ll; 10 | typedef pair P; 11 | typedef pair PP; 12 | const double eps=1e-2; 13 | ll n,m,d[MAXN][MAXN],save[MAXN][MAXN],pre[MAXN]; 14 | double d2[MAXN]; 15 | ll u[MAXM],v[MAXM],w[MAXM]; 16 | bool used[MAXN]; 17 | vector

dist[MAXN]; 18 | vector

MDST; 19 | void floyd_warshall() 20 | { 21 | for(ll k=1;k<=n;k++) 22 | for(ll i=1;i<=n;i++) 23 | for(ll j=1;j<=n;j++) d[i][j]=min(d[i][j],d[i][k]+d[k][j]); 24 | } 25 | pair absolute_center() 26 | { 27 | ll ans=INF; 28 | ll uu=-1,vv=-1; 29 | double res=0.0; 30 | for(ll i=1;i<=n;i++) 31 | { 32 | int sz=(int)dist[i].size(); 33 | if(dist[i][sz-1].F+dist[i][sz-2].F0&&used[dist[v[i]][now].S]) now--; 47 | double pos=(dist[u[i]][j].F+dist[v[i]][now].F+w[i])/2.0-dist[u[i]][j].F; 48 | if(poseps) continue; 49 | if(dist[u[i]][j].F+dist[v[i]][now].F+w[i],greater > que; 65 | d2[p.F.F]=p.S; d2[p.F.S]=d[p.F.F][p.F.S]-p.S; 66 | que.push(PP(d2[p.F.F],p.F.F)); if(p.F.F!=p.F.S) que.push(PP(d2[p.F.S],p.F.S)); 67 | while(!que.empty()) 68 | { 69 | PP p=que.top(); que.pop(); 70 | ll v=p.S; 71 | if(d2[v]d2[v]+save[v][to]) 75 | { 76 | d2[to]=d2[v]+save[v][to]; 77 | pre[to]=v; 78 | que.push(PP(d2[to],to)); 79 | } 80 | } 81 | } 82 | if(p.F.F!=p.F.S) MDST.push_back(P(p.F.F,p.F.S)); 83 | for(ll i=1;i<=n;i++) if(pre[i]!=-1) MDST.push_back(P(pre[i],i)); 84 | } 85 | int main() 86 | { 87 | scanf("%lld%lld",&n,&m); 88 | for(ll i=1;i<=n;i++) 89 | for(ll j=1;j<=n;j++) 90 | d[i][j]=save[i][j]=(i==j?0:INF); 91 | for(ll i=0;i 2 | #define MAXN 100005 3 | #define INF 1000000000 4 | #define MOD 1000000007 5 | #define F first 6 | #define S second 7 | using namespace std; 8 | int n,m,deg[MAXN],a[MAXN],cnt[MAXN],r[MAXN]; 9 | vector G[MAXN]; 10 | vector gr[MAXN]; 11 | bool cmp(int x,int y) 12 | { 13 | return deg[x]r[i]) gr[i].push_back(to); 30 | int ans=0; 31 | for(int i=1;i<=n;i++) 32 | { 33 | for(auto u:G[i]) 34 | { 35 | for(auto to:gr[u]) 36 | { 37 | if(r[to]>r[i]) 38 | { 39 | ans+=cnt[to]; 40 | cnt[to]++; 41 | } 42 | } 43 | } 44 | for(auto u:G[i]) 45 | { 46 | for(auto to:gr[u]) 47 | { 48 | if(r[to]>r[i]) cnt[to]--; 49 | } 50 | } 51 | printf("%d\n",ans); 52 | } 53 | printf("%d\n",ans); 54 | return 0; 55 | } 56 | -------------------------------------------------------------------------------- /Graph/Others/Tarjan.cpp: -------------------------------------------------------------------------------- 1 | #pragma GCC optimize(3) 2 | #include 3 | #define MAXN 100005 4 | #define INF 1000000000 5 | #define MOD 1000000007 6 | #define F first 7 | #define S second 8 | using namespace std; 9 | typedef long long ll; 10 | typedef pair P; 11 | vector G[MAXN]; 12 | int n,dfn[MAXN],low[MAXN],st[MAXN]; 13 | int vis[MAXN]; 14 | int cmp[MAXN],cnt,tot,t; 15 | void dfs(int v) 16 | { 17 | dfn[v]=low[v]=++tot; 18 | vis[v]=1; 19 | st[t++]=v; 20 | for(auto to:G[v]) 21 | { 22 | if(!vis[to]) 23 | { 24 | dfs(to); 25 | low[v]=min(low[v],low[to]); 26 | } 27 | else if(vis[to]==1) low[v]=min(low[v],dfn[to]); 28 | } 29 | if(dfn[v]==low[v]) 30 | { 31 | int u; 32 | do 33 | { 34 | u=st[t-1]; t--; 35 | cmp[u]=cnt; 36 | vis[u]=2; 37 | }while(u!=v); 38 | cnt++; 39 | } 40 | } 41 | int tarjan() 42 | { 43 | t=tot=cnt=0; 44 | memset(vis,0,sizeof(vis)); 45 | for(int i=1;i<=n;i++) if(!dfn[i]) dfs(i); 46 | return cnt; 47 | } 48 | 49 | -------------------------------------------------------------------------------- /Graph/Others/TopologicalSort.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #define MAXV 100005 3 | using namespace std; 4 | int V,t; 5 | vector G[MAXV]; 6 | int d[MAXV],f[MAXV],p[MAXV],color[MAXV]; 7 | deque order; 8 | void dfs_visit(int v) 9 | { 10 | d[v]=++t; 11 | color[v]=1; 12 | for(int i=0;i 3 | #define MAXN 10005 4 | #define MAXLOGN 14 5 | #define INF 1000000000 6 | #define MOD 1000000007 7 | #define F first 8 | #define S second 9 | using namespace std; 10 | typedef long long ll; 11 | typedef pair P; 12 | int T,n,q,k,a[MAXN]; 13 | vector G[MAXN]; 14 | int pa[MAXLOGN][MAXN]; 15 | int depth[MAXN]; 16 | void dfs(int v,int p,int d) 17 | { 18 | pa[0][v]=p; 19 | depth[v]=d; 20 | for(int i=0;i<(int)G[v].size();i++) 21 | if(G[v][i]!=p) dfs(G[v][i],v,d+1); 22 | } 23 | void init(int V) 24 | { 25 | dfs(1,0,0); 26 | for(int k=0;k+1>k)&1) 39 | v=pa[k][v]; 40 | return v; 41 | } 42 | int lca(int u,int v) 43 | { 44 | if(depth[u]>depth[v]) swap(u,v); 45 | v=get(v,depth[v]-depth[u]); 46 | if(u==v) return u; 47 | for(int k=MAXLOGN-1;k>=0;k--) 48 | { 49 | if(pa[k][u]!=pa[k][v]) 50 | { 51 | u=pa[k][u]; 52 | v=pa[k][v]; 53 | } 54 | } 55 | return pa[0][u]; 56 | } 57 | int dis(int u,int v) 58 | { 59 | return depth[u]+depth[v]-2*depth[lca(u,v)]; 60 | } 61 | bool cmp(int x,int y) 62 | { 63 | return depth[x]>depth[y]; 64 | } 65 | int main() 66 | { 67 | scanf("%d",&T); 68 | int tot=0; 69 | while(T--) 70 | { 71 | scanf("%d",&n); 72 | for(int i=1;i<=n;i++) G[i].clear(); 73 | for(int i=0;i=depth[l2])||(t2==l1&&depth[t2]>=depth[l2])) f=true; 97 | if((t3==l2&&depth[t3]>=depth[l1])||(t4==l2&&depth[t4]>=depth[l1])) f=true; 98 | if(!f) continue; 99 | int a[4]; 100 | a[0]=lca(u,vv);a[1]=lca(u,uu);a[2]=lca(v,vv);a[3]=lca(v,uu); 101 | sort(a,a+4,cmp); 102 | u=a[0],v=a[1]; 103 | } 104 | if(!f) puts("0"); else printf("%d\n",dis(u,v)+1); 105 | } 106 | } 107 | return 0; 108 | } 109 | -------------------------------------------------------------------------------- /Graph/Others/TriangleCount.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #define MAXN 100005 3 | #define INF 1000000000 4 | #define MOD 1000000007 5 | #define F first 6 | #define S second 7 | using namespace std; 8 | int n,m,deg[MAXN],a[MAXN],cnt[MAXN],r[MAXN]; 9 | vector G[MAXN]; 10 | vector gr[MAXN]; 11 | bool cmp(int x,int y) 12 | { 13 | return deg[x]r[i]) gr[i].push_back(to); 30 | int ans=0; 31 | for(int i=1;i<=n;i++) 32 | { 33 | for(auto u:gr[i]) cnt[u]++; 34 | for(auto u:gr[i]) 35 | for(auto to:gr[u]) ans+=cnt[to]; 36 | for(auto u:gr[i]) cnt[u]--; 37 | } 38 | printf("%d\n",ans); 39 | return 0; 40 | } 41 | -------------------------------------------------------------------------------- /Graph/Shortest Path Algorithms/BellmanFord.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #define MAXV 1000 3 | #define MAXE 10000 4 | #define INF 1000000 5 | using namespace std; 6 | struct edge{int from,to,cost;}; 7 | edge es[MAXE]; 8 | int d[MAXV]; 9 | int V,E; 10 | void shortest_path(int s) 11 | { 12 | for(int i=0;id[e.from]+e.cost) 21 | { 22 | d[e.to]=d[e.from]+e.cost; 23 | update=true; 24 | } 25 | } 26 | if(!update) break; 27 | } 28 | } 29 | int main() 30 | { 31 | return 0; 32 | } 33 | -------------------------------------------------------------------------------- /Graph/Shortest Path Algorithms/DijkstraI.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #define MAXV 1000 3 | #define MAXE 10000 4 | #define INF 1000000 5 | using namespace std; 6 | struct edge{int to,cost;}; 7 | typedef pair P; 8 | int V; 9 | vector G[MAXV]; 10 | int d[MAXV]; 11 | void dijkstra(int s) 12 | { 13 | priority_queue,greater

> que; 14 | fill(d,d+V,INF); 15 | d[s]=0; 16 | que.push(P(0,s)); 17 | while(!que.empty()) 18 | { 19 | P p=que.top(); que.pop(); 20 | int v=p.second; 21 | if(d[v]d[v]+e.cost) 26 | { 27 | d[e.to]=d[v]+e.cost; 28 | que.push(P(d[e.to],e.to)); 29 | } 30 | } 31 | } 32 | } 33 | int main() 34 | { 35 | return 0; 36 | } 37 | -------------------------------------------------------------------------------- /Graph/Shortest Path Algorithms/DijkstraII.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #define MAXV 1000 3 | #define MAXE 10000 4 | #define INF 1000000 5 | using namespace std; 6 | int cost[MAXV][MAXV]; 7 | int d[MAXV]; 8 | bool used[MAXV]; 9 | int V; 10 | void dijkstra(int s) 11 | { 12 | fill(d,d+V,INF); 13 | fill(used,used+V,false); 14 | d[s]=0; 15 | while(true) 16 | { 17 | int v=-1; 18 | for(int u=0;u 2 | #define MAXN 505 3 | using namespace std; 4 | int n,d[MAXN][MAXN]; 5 | void floyd_warshall() 6 | { 7 | for(int k=1;k<=n;k++) 8 | for(int i=1;i<=n;i++) 9 | for(int j=1;j<=n;j++) d[i][j]=min(d[i][j],d[i][k]+d[k][j]); 10 | } 11 | -------------------------------------------------------------------------------- /Graph/Shortest Path Algorithms/SPFA.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #define MAXV 1000 3 | #define MAXE 10000 4 | #define INF 1000000 5 | using namespace std; 6 | struct edge{int to,cost;}; 7 | typedef pair P; 8 | int V; 9 | vector G[MAXV]; 10 | int d[MAXV]; 11 | bool inque[MAXV]; 12 | queue que; 13 | void spfa(int s) 14 | { 15 | fill(d,d+V,INF); 16 | fill(inque,inque+V,false); 17 | d[s]=0; 18 | while(!que.empty()) que.pop(); 19 | que.push(s); 20 | inque[s]=true; 21 | while(!que.empty()) 22 | { 23 | int u=que.front(); 24 | que.pop(); 25 | for(int i=0;i 2 | #define rep(i,a,n) for (int i=a;i=a;i--) 4 | #define pb push_back 5 | #define mp make_pair 6 | #define all(x) (x).begin(),(x).end() 7 | #define fi first 8 | #define se second 9 | #define SZ(x) ((int)(x).size()) 10 | using namespace std; 11 | typedef vector VI; 12 | typedef long long ll; 13 | typedef pair PII; 14 | const ll mod=1000000007; 15 | ll pow_mod(ll a,ll i) 16 | { 17 | ll s=1; 18 | while(i) 19 | { 20 | if(i&1) s=s*a%mod; 21 | a=a*a%mod; 22 | i>>=1; 23 | } 24 | return s; 25 | } 26 | namespace linear_seq 27 | { 28 | const int N=10010; 29 | ll res[N],base[N],_c[N],_md[N]; 30 | vector Md; 31 | void mul(ll *a,ll *b,int k) 32 | { 33 | rep(i,0,k+k) _c[i]=0; 34 | rep(i,0,k) if(a[i]) rep(j,0,k) _c[i+j]=(_c[i+j]+a[i]*b[j])%mod; 35 | for(int i=k+k-1;i>=k;i--) 36 | if(_c[i]) rep(j,0,SZ(Md)) _c[i-k+Md[j]]=(_c[i-k+Md[j]]-_c[i]*_md[Md[j]])%mod; 37 | rep(i,0,k) a[i]=_c[i]; 38 | } 39 | int solve(ll n,VI a,VI b)//a:coefficient b:initial value b[n+1]=a[0]*b[n]+... 40 | { 41 | ll ans=0,pnt=0; 42 | int k=SZ(a); 43 | assert(SZ(a)==SZ(b)); 44 | rep(i,0,k) _md[k-1-i]=-a[i]; 45 | _md[k]=1; 46 | Md.clear(); 47 | rep(i,0,k) if(_md[i]!=0) Md.push_back(i); 48 | rep(i,0,k) res[i]=base[i]=0; 49 | res[0]=1; 50 | while((1ll<=0;p--) 52 | { 53 | mul(res,res,k); 54 | if((n>>p)&1) 55 | { 56 | for(int i=k-1;i>=0;i--) res[i+1]=res[i]; 57 | res[0]=0; 58 | rep(j,0,SZ(Md)) res[Md[j]]=(res[Md[j]]-res[k]*_md[Md[j]])%mod; 59 | } 60 | } 61 | rep(i,0,k) ans=(ans+res[i]*b[i])%mod; 62 | if(ans<0) ans+=mod; 63 | return ans; 64 | } 65 | VI BM(VI s) 66 | { 67 | VI C(1,1),B(1,1); 68 | int L=0,m=1,b=1; 69 | rep(n,0,SZ(s)) 70 | { 71 | ll d=0; 72 | rep(i,0,L+1) d=(d+(ll)C[i]*s[n-i])%mod; 73 | if(d==0) ++m; 74 | else if(2*L<=n) 75 | { 76 | VI T=C; 77 | ll c=mod-d*pow_mod(b,mod-2)%mod; 78 | while(SZ(C) 2 | #define MAXN 105 3 | #define INF 1000000000 4 | #define MOD 1000000007 5 | #define F first 6 | #define S second 7 | using namespace std; 8 | typedef long long ll; 9 | typedef pair P; 10 | int n,k; 11 | int r[MAXN][MAXN],x[MAXN]; 12 | int extgcd(int a,int b,int &x,int &y) 13 | { 14 | int d=a; 15 | if(b!=0) 16 | { 17 | d=extgcd(b,a%b,y,x); 18 | y-=(a/b)*x; 19 | } 20 | else 21 | { 22 | x=1; 23 | y=0; 24 | } 25 | return d; 26 | } 27 | int mod_inverse(int a,int m) 28 | { 29 | int x,y; 30 | extgcd(a,m,x,y); 31 | return (m+x%m)%m; 32 | } 33 | int solve(vector

&v) 34 | { 35 | int n=v.size(); 36 | for(int i=0;i v; 61 | v.push_back(P(4,7)); 62 | v.push_back(P(3,13)); 63 | printf("%d\n",solve(v)); 64 | return 0; 65 | } 66 | 67 | -------------------------------------------------------------------------------- /Math/DIVCNT1.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #define MAXN 10000005 3 | #define INF 100000000 4 | #define MOD 100000007 5 | #define F first 6 | #define S second 7 | using namespace std; 8 | typedef long long ll; 9 | typedef __int128 lll; 10 | struct frac 11 | { 12 | ll x,y; 13 | frac(ll _x=0,ll _y=0) {x=_x; y=_y;} 14 | frac operator +(const frac &t) const 15 | { 16 | return frac(x+t.x,y+t.y); 17 | } 18 | }st[MAXN],L,R,M; 19 | 20 | int T; 21 | ll n; 22 | bool inR(ll x,ll y) {return x*y<=n;} 23 | double slope(ll x) {return (double)n/x/x;} 24 | 25 | inline void write(lll x){ 26 | if(x>=10)write(x/10); 27 | putchar(x%10+'0'); 28 | } 29 | 30 | inline void writeln(const lll &x){ 31 | write(x); 32 | putchar('\n'); 33 | } 34 | 35 | lll solve(ll n) 36 | { 37 | lll ret=0; 38 | int t=0,rt=cbrt(n); 39 | st[++t]=frac(1,0); 40 | st[++t]=frac(1,1); 41 | ll m=sqrt(n),x=n/m,y=m+1; 42 | while(true) 43 | { 44 | for(L=st[t--];!inR(x+L.x,y-L.y);x+=L.x,y-=L.y) 45 | ret+=x*L.y+(L.y+1)*(L.x-1)/2; 46 | if(y<=rt) break; 47 | for(R=st[t];inR(x+R.x,y-R.y);R=st[--t]) L=R; 48 | while(true) 49 | { 50 | M=L+R; 51 | if(!inR(x+M.x,y-M.y)) st[++t]=(R=M); 52 | else 53 | { 54 | if(slope(x+M.x)<=(double)R.y/R.x) break; 55 | L=M; 56 | } 57 | } 58 | } 59 | for(int i=1;i 2 | #define MAXN 505 3 | using namespace std; 4 | typedef vector vec; 5 | typedef vector mat; 6 | int n; 7 | int det_mod(mat A,int M) 8 | { 9 | int n=A.size(); 10 | for(int i=0;i 2 | #define MAXN 100005 3 | #define MOD 1000000007 4 | #define INF 1000000000 5 | using namespace std; 6 | typedef long long ll; 7 | int prime[MAXN]; 8 | bool is_prime[MAXN]; 9 | int sieve(int n) 10 | { 11 | int p=0; 12 | for(int i=0;i<=n;i++) is_prime[i]=true; 13 | is_prime[0]=is_prime[1]=false; 14 | for(int i=2;i<=n;i++) 15 | { 16 | if(is_prime[i]) 17 | { 18 | prime[p++]=i; 19 | for(int j=2*i;j<=n;j+=i) is_prime[j]=false; 20 | } 21 | } 22 | return p; 23 | } 24 | 25 | 26 | -------------------------------------------------------------------------------- /Math/Euclid.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #define MAXN 100005 3 | #define INF 1000000000 4 | #define MOD 1000000007 5 | #define F first 6 | #define S second 7 | using namespace std; 8 | typedef long long ll; 9 | typedef pair P; 10 | ll inv2,inv6,a,b,c,l,r;//need initialize 11 | struct E 12 | { 13 | ll f,g,h; 14 | E(){} 15 | E(ll _f,ll _g,ll _h){f=_f,g=_g,h=_h;} 16 | }; 17 | ll pow_mod(ll a,ll i) 18 | { 19 | ll s=1; 20 | while(i) 21 | { 22 | if(i&1) s=s*a%MOD; 23 | a=a*a%MOD; 24 | i>>=1; 25 | } 26 | return s; 27 | } 28 | // f:\sum_{i=0}^{n}\lfloor\frac{ai+b}{c}\rfloor 29 | // g:\sum_{i=0}^{n}i\times\lfloor\frac{ai+b}{c}\rfloor 30 | // g:\sum_{i=0}^{n}\lfloor\frac{ai+b}{c}\rfloor^{2} 31 | E cal(ll a,ll b,ll c,ll n) 32 | { 33 | if(!a) return E(0,0,0); 34 | E x,y; 35 | if(a>=c||b>=c) 36 | { 37 | x=cal(a%c,b%c,c,n); 38 | y.f=(a/c*n%MOD*(n+1)%MOD*inv2+b/c*(n+1)+x.f)%MOD; 39 | y.g=(a/c*n%MOD*(n+1)%MOD*(n*2+1)%MOD*inv6+b/c*(n+1)%MOD*n%MOD*inv2+x.g)%MOD; 40 | y.h=a/c*(a/c)%MOD*n%MOD*(n+1)%MOD*(n*2+1)%MOD*inv6%MOD; 41 | (y.h+=b/c*(b/c)%MOD*(n+1))%=MOD; 42 | (y.h+=a/c*(b/c)%MOD*n%MOD*(n+1))%=MOD; 43 | (y.h+=2LL*(a/c)%MOD*x.g)%=MOD; 44 | (y.h+=2LL*(b/c)%MOD*x.f)%=MOD; 45 | y.f=(y.f+MOD)%MOD;y.g=(y.g+MOD)%MOD;y.h=(y.h+MOD)%MOD; 46 | return y; 47 | } 48 | ll m=(a*n+b)/c; 49 | x=cal(c,c-b-1,a,m-1); 50 | y.f=(n*m-x.f)%MOD; 51 | y.g=y.g*inv2%MOD; 52 | y.h=(n*m%MOD*(m+1)-2LL*x.g-2LL*x.f-y.f)%MOD; 53 | y.f=(y.f+MOD)%MOD;y.g=(y.g+MOD)%MOD;y.h=(y.h+MOD)%MOD; 54 | return y; 55 | } 56 | int main() 57 | { 58 | inv2=pow_mod(2,MOD-2);inv6=pow_mod(6,MOD-2); 59 | return 0; 60 | } 61 | -------------------------------------------------------------------------------- /Math/Euler.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #define MAXN 100000 3 | using namespace std; 4 | int phi[MAXN]; 5 | int phi1(int n) 6 | { 7 | int res=n; 8 | for(int i=2;i*i<=n;i++) 9 | { 10 | if(n%i==0) 11 | { 12 | res=res/i*(i-1); 13 | for(;n%i==0;n/=i); 14 | } 15 | } 16 | if(n!=1) res=res/n*(n-1); 17 | return res; 18 | } 19 | void phi2() 20 | { 21 | for(int i=0;i 2 | #define MAXN 100005 3 | #define MOD 1000000007 4 | #define INF 1000000000 5 | using namespace std; 6 | typedef long long ll; 7 | int prime[MAXN],phi[MAXN],miu[MAXN]; 8 | bool is_prime[MAXN]; 9 | int sieve(int n) 10 | { 11 | int p=0; 12 | for(int i=0;i<=n;i++) is_prime[i]=true; 13 | is_prime[0]=is_prime[1]=false; 14 | for(int i=2;i<=n;i++) 15 | { 16 | if(is_prime[i]) prime[p++]=i; 17 | for(int j=0;jn) break; 20 | is_prime[prime[j]*i]=false; 21 | if(i%prime[j]==0) break; 22 | } 23 | } 24 | return p; 25 | } 26 | void genphi(int n) 27 | { 28 | int p=0; 29 | memset(phi,0,sizeof(phi)); 30 | phi[1]=1; 31 | for(int i=2;i<=n;i++) 32 | { 33 | if(is_prime[i]) {p++; phi[i]=i-1;} 34 | for(int j=0;jn) break; 37 | phi[i*prime[j]]=phi[i]*(i%prime[j]?prime[j]-1:prime[j]); 38 | if(i%prime[j]==0) break; 39 | } 40 | } 41 | } 42 | void genmiu(int n) 43 | { 44 | int p=0; 45 | memset(miu,0,sizeof(miu)); 46 | miu[1]=1; 47 | for(int i=2;i<=n;i++) 48 | { 49 | if(is_prime[i]) {p++; miu[i]=-1;} 50 | for(int j=0;jn) break; 53 | miu[i*prime[j]]=i%prime[j]?-miu[i]:0; 54 | if(i%prime[j]==0) break; 55 | } 56 | } 57 | } 58 | int main() 59 | { 60 | sieve(100000); 61 | genphi(100000); 62 | genmiu(100000); 63 | for(int i=1;i<=10;i++) 64 | printf("%d\n",miu[i]); 65 | return 0; 66 | } 67 | 68 | -------------------------------------------------------------------------------- /Math/ExtLucas.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #define MAXN 1000005 3 | #define MAXM 105 4 | #define INF 1000000000 5 | #define MOD 1000000007 6 | #define F first 7 | #define S second 8 | using namespace std; 9 | typedef long long ll; 10 | typedef pair P; 11 | ll n,k; 12 | bool isprime[MAXN]; 13 | int m; 14 | ll r[MAXM][MAXM],x[MAXM]; 15 | ll extgcd(ll a,ll b,ll &x,ll &y) 16 | { 17 | ll d=a; 18 | if(b!=0) 19 | { 20 | d=extgcd(b,a%b,y,x); 21 | y-=(a/b)*x; 22 | } 23 | else 24 | { 25 | x=1; 26 | y=0; 27 | } 28 | return d; 29 | } 30 | int mod_inverse(int a,int m) 31 | { 32 | ll x,y; 33 | extgcd(a,m,x,y); 34 | return (m+x%m)%m; 35 | } 36 | int solve(vector

&v) 37 | { 38 | int n=(int)v.size(); 39 | for(int i=0;i>=1; 65 | } 66 | return s; 67 | } 68 | int get_mod(ll n,int p,int pk) 69 | { 70 | if(n==0) return 1; 71 | int ans=1; 72 | for(int i=1;i<=pk;i++) if(i%p) ans=1LL*ans*i%pk; 73 | ans=pow_mod(ans,n/pk,pk); 74 | for(int i=1;i<=n%pk;i++) if(i%p) ans=1LL*ans*i%pk; 75 | ans=1LL*ans*get_mod(n/p,p,pk)%pk; 76 | return ans; 77 | } 78 | int comb(ll n,ll k,int p,int pk) 79 | { 80 | if(n v; 93 | int main() 94 | { 95 | scanf("%lld%lld%d",&n,&k,&m); 96 | memset(isprime,true,sizeof(isprime)); 97 | for(int i=2;i<=1000000;i++) 98 | for(int j=2*i;j<=1000000;j+=i) 99 | isprime[j]=false; 100 | int tmp=m; 101 | for(int i=2;i<=1000000;i++) 102 | { 103 | if(!isprime[i]) continue; 104 | if(tmp%i) continue; 105 | int p=i,pk=1; 106 | while(tmp%i==0) tmp/=i,pk*=i; 107 | v.push_back(make_pair(comb(n,k,p,pk),pk)); 108 | } 109 | printf("%d\n",solve(v)); 110 | return 0; 111 | } 112 | -------------------------------------------------------------------------------- /Math/Extgcd.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | using namespace std; 3 | typedef __int64 ll; 4 | ll extgcd(ll a,ll b,ll &x,ll &y) 5 | { 6 | ll d=a; 7 | if(b!=0) 8 | { 9 | d=extgcd(b,a%b,y,x); 10 | y-=(a/b)*x; 11 | } 12 | else 13 | { 14 | x=1; 15 | y=0; 16 | } 17 | return d; 18 | } 19 | ll a,b,x,y; 20 | int main() 21 | { 22 | while(scanf("%I64d%I64d",&a,&b)==2) 23 | { 24 | if(extgcd(a,b,x,y)==1) 25 | { 26 | while(x<0) 27 | { 28 | x+=b; 29 | y-=a; 30 | } 31 | printf("%I64d %I64d\n",x,y); 32 | } 33 | else puts("sorry"); 34 | } 35 | return 0; 36 | } 37 | -------------------------------------------------------------------------------- /Math/FWT.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #define MAXN 100005 3 | #define INF 1000000000 4 | #define MOD 1000000007 5 | #define REV 500000004 6 | #define F first 7 | #define S second 8 | using namespace std; 9 | typedef long long ll; 10 | typedef pair P; 11 | void FWT(int a[],int n) 12 | { 13 | for(int d=1;d 2 | #define MAXN 100005 3 | #define INF 1000000000 4 | #define MOD 1000000007 5 | #define F first 6 | #define S second 7 | using namespace std; 8 | typedef long long ll; 9 | typedef pair P; 10 | ll a,b,c,d,t; 11 | P cal(ll a,ll b,ll c,ll d) 12 | { 13 | //printf("%lld %lld %lld %lld\n",a,b,c,d); 14 | ll x=a/b+1;if(x*d 2 | typedef long long ll; 3 | ll mul(ll A,ll B,ll mod) 4 | { 5 | return (A*B-(ll)((long double)A*B/mod)*mod+mod)%mod; 6 | } 7 | -------------------------------------------------------------------------------- /Math/GaussJordan.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #define MAXN 105 3 | using namespace std; 4 | int sz; 5 | const double eps=1e-9; 6 | bool IsZero(double v) 7 | { 8 | return abs(v) 14 | void GaussianElimination(vector>&a, int limit, GAUSS_MODE mode=DEGREE) 15 | { 16 | if(a.empty()||a[0].empty()) return; 17 | int h=static_cast(a.size()); 18 | int w=static_cast(a[0].size()); 19 | vector deg(h); 20 | for(int i=0;ir) 32 | { 33 | swap(a[r],a[id]); swap(deg[r],deg[id]); 34 | for(int j=c;j nonzero; 37 | for(int j=c;j=0;r--) 56 | { 57 | for(int c=0;c=0;i--) 63 | { 64 | if (IsZero(a[i][c])) continue; 65 | T coeff = -a[i][c] * inv_a; 66 | for (int j = c; j < w; j++) { 67 | a[i][j] += coeff * a[r][j]; 68 | } 69 | } 70 | break; 71 | } 72 | } 73 | } 74 | } 75 | 76 | template 77 | vector SolveLinearSystem(vector> a, const vector& b, int w) { 78 | int h = static_cast(a.size()); 79 | assert(h == static_cast(b.size())); 80 | if (h > 0) { 81 | assert(w == static_cast(a[0].size())); 82 | } 83 | for (int i = 0; i < h; i++) { 84 | a[i].push_back(b[i]); 85 | } 86 | GaussianElimination(a, w); 87 | vector x(w, 0); 88 | for (int i = 0; i < h; i++) { 89 | for (int j = 0; j < w; j++) { 90 | if (!IsZero(a[i][j])) { 91 | x[j] = a[i][w] / a[i][j]; 92 | break; 93 | } 94 | } 95 | } 96 | return x; 97 | } 98 | -------------------------------------------------------------------------------- /Math/Interpolation.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #define MAXN 101 3 | using namespace std; 4 | double x[MAXN],y[MAXN]; 5 | int n; 6 | int main() 7 | { 8 | scanf("%d",&n); 9 | for(int i=0;i 2 | #define MAXN 1000 3 | using namespace std; 4 | typedef vector vec; 5 | typedef vector mat; 6 | typedef long long ll; 7 | int n; 8 | mat mul(mat A,mat B) 9 | { 10 | mat C(A.size(),vec(B[0].size())); 11 | for(int i=0;i0) 23 | { 24 | if(n&1) B=mul(B,A); 25 | A=mul(A,A); 26 | n>>=1; 27 | } 28 | return B; 29 | } 30 | int main() 31 | { 32 | scanf("%d",&n); 33 | mat A(n,vec(n)); 34 | for(int i=0;i 2 | #define MAXN 1000 3 | using namespace std; 4 | int a[MAXN],bas[62]; 5 | int n; 6 | int main() 7 | { 8 | for(int i=1;i<=n;i++) 9 | { 10 | int x=a[i]; 11 | for(int j=60;j>=0;j--) 12 | { 13 | if(x&(1ll< 2 | #define MAXN 10000 3 | using namespace std; 4 | //A_ix = B_i mod M_i 5 | ll extgcd(ll a,ll b,ll &x,ll &y)//ax+by=gcd(a,b) 6 | { 7 | ll d=a; 8 | if(b!=0) 9 | { 10 | d=extgcd(b,a%b,y,x); 11 | y-=(a/b)*x; 12 | } 13 | else 14 | { 15 | x=1; 16 | y=0; 17 | } 18 | return d; 19 | } 20 | int mod_inverse(int a,int m)//ax+km=1 21 | { 22 | int x,y; 23 | extgcd(a,m,x,y); 24 | return (m+x%m)%m; 25 | } 26 | pair linear_congruence(const vector&A, const vector&B, const vector&M) 27 | { 28 | int x=0,m=1;//sol=x mod m 29 | for(int i=0;i 2 | #define MAXN 1000 3 | using namespace std; 4 | typedef vector vec; 5 | typedef vector mat; 6 | typedef long long ll; 7 | int n; 8 | mat mul(mat A,mat B) 9 | { 10 | mat C(A.size(),vec(B[0].size())); 11 | for(int i=0;i0) 23 | { 24 | if(n&1) B=mul(B,A); 25 | A=mul(A,A); 26 | n>>=1; 27 | } 28 | return B; 29 | } 30 | int main() 31 | { 32 | scanf("%d",&n); 33 | mat A(n,vec(n)); 34 | for(int i=0;i 2 | using namespace std; 3 | int pow_mod(int a,int i,int n) 4 | { 5 | if(i==0) return 1%n; 6 | int temp=pow_mod(a,i>>1,n); 7 | temp=temp*temp%n; 8 | if(i&1) temp=(long long) temp*a%n; 9 | return temp; 10 | } 11 | bool test(int n,int a,int d) 12 | { 13 | if(n==2) return true; 14 | if(n==a) return true; 15 | if((n&1)==0) return false; 16 | while(!(d&1)) d=d>>1; 17 | int t=pow_mod(a,d,n); 18 | while((d!=n-1)&&(t!=1)&&(t!=n-1)) 19 | { 20 | t=(long long)t*t%n; 21 | d=d<<1; 22 | } 23 | return(t==n-1||(d&1)==1); 24 | } 25 | bool isPrime(int n) 26 | { 27 | if(n<2) return false; 28 | int a[]={2,3,61}; 29 | for(int i=0;i<=2;++i) if(!test(n,a[i],n-1)) return false; 30 | return true; 31 | } 32 | int main() 33 | { 34 | return 0; 35 | } 36 | -------------------------------------------------------------------------------- /Math/Mobius.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #define MAXN 1<<20 3 | using namespace std; 4 | int mu[MAXN]; 5 | void getMu() 6 | { 7 | for(int i=1;i<=n;i++) 8 | { 9 | int target=i==1?1:0; 10 | int delta=target-mu[i]; 11 | mu[i]=delta; 12 | for(int j=i+i;j<=n;j+=i) 13 | mu[j]+=delta; 14 | } 15 | return; 16 | } 17 | int main() 18 | { 19 | return 0; 20 | } 21 | -------------------------------------------------------------------------------- /Math/Mod.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #define MAXN 100000 3 | #define MAXP 1005 4 | using namespace std; 5 | int gcd(int a,int b) 6 | { 7 | if(b==0) return a; 8 | return gcd(b,a%b); 9 | } 10 | int extgcd(int a,int b,int &x,int &y) 11 | { 12 | int d=a; 13 | if(b!=0) 14 | { 15 | d=extgcd(b,a%b,y,x); 16 | y-=(a/b)*x; 17 | } 18 | else 19 | { 20 | x=1; 21 | y=0; 22 | } 23 | return d; 24 | } 25 | int mod_inverse(int a,int m) 26 | { 27 | int x,y; 28 | extgcd(a,m,x,y); 29 | return (m+x%m)%m; 30 | } 31 | int fact[MAXP]; 32 | int mod_fact(int n,int p,int &e) 33 | { 34 | e=0; 35 | if(n==0) return 1; 36 | int res=mod_fact(n/p,p,e); 37 | e+=n/p; 38 | if(n/p%2!=0) return res*(p-fact[n%p])%p; 39 | return res*fact[n%p]%p; 40 | } 41 | int mod_comb(int n,int k,int p) 42 | { 43 | if(n<0||k<0||ne2+e3) return 0; 47 | return a1*mod_inverse(a2*a3%p,p)%p; 48 | } 49 | int main() 50 | { 51 | inv[1]=1; 52 | for (int i=2;i 2 | #define MAXN 100005 3 | #define MOD 998244353 4 | #define INF 1000000000 5 | #define F first 6 | #define S second 7 | using namespace std; 8 | typedef long long ll; 9 | typedef pair P; 10 | const int g=3; 11 | int two[31]; 12 | int dbit(int x) 13 | { 14 | while(x!=(x&-x)) x+=(x&-x); 15 | return x; 16 | } 17 | int pow_mod(int a,int i) 18 | { 19 | if(i==0) return 1; 20 | int s=1; 21 | while(i>0) 22 | { 23 | if(i&1) s=(1LL*s*a)%MOD; 24 | a=(1LL*a*a)%MOD; 25 | i>>=1; 26 | } 27 | return s; 28 | } 29 | int rev(int x,int r) 30 | { 31 | int ans=0; 32 | for(int i=0;i1) {cnt++; t/=2;} 40 | for(;;r++) if((1<=MOD) A[k+j]-=MOD; 60 | A[k+j+m/2]=u+MOD-t; 61 | if(A[k+j+m/2]>=MOD) A[k+j+m/2]-=MOD; 62 | w=1LL*w*wn%MOD; 63 | } 64 | } 65 | } 66 | if(on==-1) 67 | { 68 | for(int i=1;i>s1>>s2) 83 | { 84 | n=s1.size(); 85 | m=s2.size(); 86 | memset(A,0,sizeof(A)); 87 | memset(B,0,sizeof(B)); 88 | for(int i=n-1; i>=0 ; i--) 89 | A[i]=s1[n-i-1]-'0'; 90 | for(int i=m-1; i>=0; i--) 91 | B[i]=s2[m-i-1]-'0'; 92 | int tmp=1; 93 | while(tmp=10) 106 | { 107 | ans[i+1]+=ans[i]/10; 108 | ans[i]%=10; 109 | } 110 | } 111 | int e=0; 112 | for(int i=2*n-1;i>=0;i--) 113 | { 114 | if(ans[i]) 115 | { 116 | e=i; 117 | break; 118 | } 119 | } 120 | for(int i=e;i>=0;i--) 121 | { 122 | printf("%d",ans[i]); 123 | } 124 | printf("\n"); 125 | } 126 | return 0; 127 | } 128 | -------------------------------------------------------------------------------- /Math/Pell.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #define MAXN 10005 3 | #define F first 4 | #define S second 5 | using namespace std; 6 | typedef pair P; 7 | P Pell(int N) 8 | { 9 | int p0=0,p1=1,q0=1,q1=0; 10 | int a0=(int)sqrt(N),a1=a0,a2=a0; 11 | if(a0*a0==N) return P(-1,-1); 12 | int g1=0,h1=1; 13 | while(true) 14 | { 15 | int g2=-g1+a1*h1; 16 | int h2=(N-g2*g2)/h1; 17 | a2=(g2+a0)/h2; 18 | int p2=a1*p1+p0; 19 | int q2=a1*q1+q0; 20 | if(p2*p2-N*q2*q2==1) return P(p2,q2); 21 | a1=a2;g1=g2;h1=h2;p0=p1;p1=p2;q0=q1;q1=q2; 22 | } 23 | } 24 | int main() 25 | { 26 | int n; 27 | while(scanf("%d",&n)==1) 28 | { 29 | P p=Pell(n); 30 | printf("%d %d\n",p.F,p.S); 31 | } 32 | return 0; 33 | } -------------------------------------------------------------------------------- /Math/PohligHellman.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #define MAXN 100005 3 | #define INF 1000000000 4 | #define MOD 1000000007 5 | #define F first 6 | #define S second 7 | using namespace std; 8 | typedef long long ll; 9 | typedef pair P; 10 | int T; 11 | ll a,b,p; 12 | ll mul(ll A,ll B,ll mod) 13 | { 14 | return (A*B-(ll)((long double)A*B/mod)*mod+mod)%mod; 15 | } 16 | ll pow_mod(ll a,ll i,ll mod) 17 | { 18 | if(i==0) return 1; 19 | ll s=1; 20 | while(i>0) 21 | { 22 | if(i&1) s=mul(s,a); 23 | a=mul(a,a); 24 | i>>=1; 25 | } 26 | return s; 27 | } 28 | 29 | vector

fact; 30 | 31 | ll Pohlig_Hellman(ll g,ll x,ll p,vector

fact) 32 | { 33 | ll q=p-1,now=g,res=1,ker=0; 34 | for(int i=0;i<(int)fact.size();i++) 35 | { 36 | for(int j=0;j 2 | 3 | using namespace std; 4 | using i64 = int64_t; 5 | int T; 6 | 7 | i64 solve_fast(i64 N) { 8 | auto inside = [N] (i64 x, i64 y) { 9 | return x * x + y * y <= N; 10 | }; 11 | auto cut = [] (i64 x, i64 y, int dx1, int dy1) { 12 | return dx1 * x >= dy1 * y; 13 | }; 14 | 15 | const i64 v = sqrtl(N / 2), w = sqrtl(N); 16 | i64 x = v; 17 | i64 y = i64(sqrtl(max(0, N - (v + 1) * (v + 1)))) + 1; 18 | 19 | auto stac = stack< pair >({{0, 1}, {1, 1}}); 20 | 21 | i64 ret = 0; 22 | while (1) { 23 | int dx1, dy1; tie(dx1, dy1) = stac.top(); stac.pop(); 24 | while (inside(x + dx1, y - dy1)) 25 | { 26 | x += dx1; y -= dy1; 27 | ret += i64(dx1) * (y - 1) 28 | + ((i64(dx1 + 1) * (dy1 + 1)) >> 1) - dy1; 29 | } 30 | 31 | int dx2 = dx1, dy2 = dy1; 32 | while (!stac.empty()) { 33 | tie(dx1, dy1) = stac.top(); 34 | if (inside(x + dx1, y - dy1)) break; 35 | stac.pop(); 36 | dx2 = dx1, dy2 = dy1; 37 | } 38 | if (stac.empty()) break; 39 | 40 | while (1) { 41 | int dx12 = dx1 + dx2, dy12 = dy1 + dy2; 42 | if (inside(x + dx12, y - dy12)) { 43 | stac.emplace(dx1 = dx12, dy1 = dy12); 44 | } else { 45 | if (cut(x + dx12, y - dy12, dx1, dy1)) break; 46 | dx2 = dx12, dy2 = dy12; 47 | } 48 | } 49 | } 50 | ret = ret * 2 + i64(v) * v; 51 | ret = ret * 4 + 4 * i64(w) + 1; 52 | return ret; 53 | } 54 | 55 | int main() 56 | { 57 | i64 N = 1e18; 58 | // printf("%llu\n", solve_naive(N)); 59 | printf("%llu\n", solve_fast(N)); 60 | return 0; 61 | } 62 | -------------------------------------------------------------------------------- /Math/PollardRho.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #define MAXN 1005 3 | #define INF 1000000000 4 | #define MOD 1000000007 5 | #define F first 6 | #define S second 7 | using namespace std; 8 | typedef unsigned long long ULL; 9 | //to achieve best running time, sieve until 2/3 prime factors remaining 10 | namespace pollardrho 11 | { 12 | ULL gcd(ULL a, ULL b) {return b ? gcd(b, a % b) : a;} 13 | 14 | ULL mulmod(ULL x,ULL y,ULL p) 15 | { 16 | ULL z=(long double)x/p*y; 17 | ULL res=(ULL)x*y-(ULL)z*p; 18 | return (res+p)%p; 19 | } 20 | 21 | ULL powmod(ULL b, ULL e, ULL m) 22 | { 23 | ULL r = 1; 24 | while (e) 25 | { 26 | if (e & 1) r = mulmod(r, b, m); 27 | b = mulmod(b, b, m); 28 | e >>= 1; 29 | } 30 | return r; 31 | } 32 | 33 | bool test(ULL n) 34 | { 35 | if (n < 3) return n==2; 36 | // ! The array a[] should be modified if the range of x changes. 37 | static const ULL a[] = {2, 3, 5, 7, 11, 13, 17, 19, 23, ULLONG_MAX};//works for 1e18 38 | ULL r = 0, d = n-1, x; 39 | while (~d & 1) d >>= 1, r++; 40 | for (int i=0; a[i] < n; i++) 41 | { 42 | x = powmod(a[i], d, n); 43 | if (x == 1 || x == n-1) goto next; 44 | for(int i=0;i mp; 56 | mt19937_64 gen(time(NULL)); 57 | 58 | void PollardRho(ULL n) 59 | { 60 | ULL c, x, y, d; 61 | while (n % 2 == 0) 62 | { 63 | mp[2]++; 64 | n /= 2; 65 | } 66 | if (n == 1) return; 67 | 68 | if (test(n)) 69 | { 70 | mp[n]++; 71 | return; 72 | } 73 | 74 | d = n; 75 | static int counter = 0; 76 | while (d == n) 77 | { 78 | x = y = 2; 79 | d = 1; 80 | c = gen() % (n - 1) + 1; 81 | while (d == 1) 82 | { 83 | counter++; 84 | x = (mulmod(x, x, n) + c) % n; 85 | y = (mulmod(y, y, n) + c) % n; 86 | y = (mulmod(y, y, n) + c) % n; 87 | d = gcd(x > y ? x - y : y - x, n); 88 | } 89 | } 90 | PollardRho(d); 91 | PollardRho(n / d); 92 | } 93 | 94 | void work(ULL n,int id) 95 | { 96 | PollardRho(n); 97 | for(auto p:mp) fact[id].push_back(p); 98 | mp.clear(); 99 | } 100 | } -------------------------------------------------------------------------------- /Math/PolySum.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #define MAXN 100005 3 | #define INF 1000000000 4 | #define MOD 1000000007 5 | #define F first 6 | #define S second 7 | using namespace std; 8 | typedef long long ll; 9 | typedef pair P; 10 | int pow_mod(int a,int i) 11 | { 12 | int s=1; 13 | while(i) 14 | { 15 | if(i&1) s=1LL*s*a%MOD; 16 | a=1LL*a*a%MOD; 17 | i>>=1; 18 | } 19 | return s; 20 | } 21 | int gcd(int a,int b) 22 | { 23 | if(b==0) return a; 24 | return gcd(b,a%b); 25 | } 26 | namespace polysum 27 | { 28 | const int D=100005; 29 | int a[D],f[D],g[D],p[D],p1[D],p2[D],b[D],h[D][2],C[D]; 30 | int calcn(int d,int *a,int n) 31 | { 32 | if(n<=d) return a[n]; 33 | p1[0]=p2[0]=1; 34 | for(int i=0;i<=d;i++) 35 | { 36 | int t=(n-i+MOD)%MOD; 37 | p1[i+1]=1LL*p1[i]*t%MOD; 38 | } 39 | for(int i=0;i<=d;i++) 40 | { 41 | int t=(n-d+i+MOD)%MOD; 42 | p2[i+1]=1LL*p2[i]*t%MOD; 43 | } 44 | ll ans=0; 45 | for(int i=0;i<=d;i++) 46 | { 47 | int t=1LL*g[i]*g[d-i]%MOD*p1[i]%MOD*p2[d-i]%MOD*a[i]%MOD; 48 | if((d-i)&1) ans=(ans-t+MOD)%MOD; 49 | else ans=(ans+t)%MOD; 50 | } 51 | return ans; 52 | } 53 | void init(int M) 54 | { 55 | f[0]=f[1]=g[0]=g[1]=1; 56 | for(int i=2;i<=M+4;i++) f[i]=1LL*f[i-1]*i%MOD; 57 | g[M+4]=pow_mod(f[M+4],MOD-2); 58 | for(int i=M+3;i>=1;i--) g[i]=1LL*g[i+1]*(i+1)%MOD; 59 | } 60 | int polysum(int n,int *a,int m) //a[0]..a[m] \sum_{i=0}^{n-1} a[i] 61 | { 62 | a[m+1]=calcn(m,a,m+1); 63 | for(int i=1;i<=m+1;i++) a[i]=(a[i-1]+a[i])%MOD; 64 | return calcn(m+1,a,n-1); 65 | } 66 | int qpolysum(int R,int n,int *a,int m) //a[0]..a[m] \sum_{i=0}^{n-1} a[i]*R^i 67 | { 68 | if(R==1) return polysum(n,a,m); 69 | a[m+1]=calcn(m,a,m+1); 70 | int r=pow_mod(R,MOD-2),p3=0,p4=0,c,ans; 71 | h[0][0]=0;h[0][1]=1; 72 | for(int i=1;i<=m+1;i++) 73 | { 74 | h[i][0]=1LL*(h[i-1][0]+a[i-1])*r%MOD; 75 | h[i][1]=1LL*h[i-1][1]*r%MOD; 76 | } 77 | for(int i=0;i<=m+1;i++) 78 | { 79 | int t=1LL*g[i]*g[m+1-i]%MOD; 80 | if(i&1) p3=((p3-1LL*h[i][0]*t)%MOD+MOD)%MOD,p4=((p4-1LL*h[i][1]*t)%MOD+MOD)%MOD; 81 | else p3=(p3+1LL*h[i][0]*t)%MOD,p4=(p4+1LL*h[i][1]*t)%MOD; 82 | } 83 | c=1LL*pow_mod(p4,MOD-2)*(MOD-p3)%MOD; 84 | for(int i=0;i<=m+1;i++) h[i][0]=(h[i][0]+1LL*h[i][1]*c)%MOD; 85 | for(int i=0;i<=m+1;i++) C[i]=h[i][0]; 86 | ans=(1LL*calcn(m,C,n)*pow_mod(R,n)-c)%MOD; 87 | if(ans<0) ans+=MOD; 88 | return ans; 89 | } 90 | } 91 | ll a[MAXN]; 92 | int main() 93 | { 94 | a[0]=1;a[1]=100;a[2]=0; 95 | polysum::init(1000); 96 | printf("%lld\n",polysum::qpolysum(2,4,a,1)); 97 | return 0; 98 | } 99 | -------------------------------------------------------------------------------- /Math/PowMod.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | using namespace std; 3 | typedef long long ll; 4 | ll pow_mod(ll a,ll i) 5 | { 6 | if(i==0) return 1; 7 | ll s=1; 8 | while(i>0) 9 | { 10 | if(i&1) s=(s*a)%MOD; 11 | a=(a*a)%MOD; 12 | i>>=1; 13 | } 14 | return s; 15 | } 16 | int main() 17 | { 18 | return 0; 19 | } 20 | -------------------------------------------------------------------------------- /Math/PowerTower.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #define MAXN 100005 3 | #define INF 1000000000 4 | #define MOD 1000000007 5 | #define F first 6 | #define S second 7 | using namespace std; 8 | typedef long long ll; 9 | typedef pair P; 10 | int n,m,q,a[MAXN]; 11 | unordered_map phi; 12 | int f(ll x,int m) {return x>=1; 21 | } 22 | return s; 23 | } 24 | int getphi(int n) 25 | { 26 | if(phi.find(n)!=phi.end()) return phi[n]; 27 | int res=n; 28 | for(int i=2;i*i<=n;i++) 29 | { 30 | if(n%i==0) 31 | { 32 | res=res/i*(i-1); 33 | for(;n%i==0;n/=i); 34 | } 35 | } 36 | if(n!=1) res=res/n*(n-1); 37 | return phi[n]=res; 38 | } 39 | //calculate power tower in [l,r] modulo m 40 | //need to modulo m outside the recursion 41 | int solve(int l,int r,int m) 42 | { 43 | if(m==1||l>r||a[l]==1) return 1; 44 | return pow_mod(f(a[l],m),solve(l+1,r,getphi(m)),m); 45 | } 46 | -------------------------------------------------------------------------------- /Math/PrimitiveRoot.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include 9 | #include 10 | #include 11 | #include 12 | #define MAXN 1005000 13 | using namespace std; 14 | typedef long long ll; 15 | vector a; 16 | ll pow_mod(ll a,ll i,ll mod) 17 | { 18 | if(i==0) return 1; 19 | ll s=1; 20 | while(i>0) 21 | { 22 | if(i&1) s=(s*a)%mod; 23 | a=(a*a)%mod; 24 | i>>=1; 25 | } 26 | return s; 27 | } 28 | bool g_test(ll g,ll p) 29 | { 30 | for(ll i=0;i 2 | #include 3 | #include 4 | 5 | using namespace std; 6 | 7 | typedef vector perm; 8 | typedef long long llong; 9 | 10 | perm operator *(const perm& a, const perm& b) { 11 | assert(a.size() == b.size()); 12 | perm c(a.size()); 13 | for (int i = 0; i < a.size(); i++) { 14 | c[i] = a[b[i]]; 15 | } 16 | return c; 17 | } 18 | 19 | perm inv(const perm& a) { 20 | perm c(a.size()); 21 | for (int i = 0; i < a.size(); i++) 22 | c[a[i]] = i; 23 | return c; 24 | } 25 | 26 | perm identity(int n) { 27 | perm c(n); 28 | for (int i = 0; i < n; i++) 29 | c[i] = i; 30 | return c; 31 | } 32 | 33 | void DFS(const perm& cur, const vector& generators, vector& sigma) { 34 | sigma[cur[0]] = cur; 35 | for (const perm& g : generators) { 36 | perm y = g * cur; 37 | if (sigma[y[0]].empty()) { 38 | DFS(y, generators, sigma); 39 | } 40 | } 41 | } 42 | 43 | void reduceGenerators(vector& generators) { 44 | if (generators.empty()) 45 | return; 46 | int n = generators.front().size(); 47 | int pt = 0; 48 | for (int i = 0; i < n; i++) { 49 | vector posByFirst(n, -1); 50 | for (int j = pt; j < generators.size(); j++) { 51 | perm& g = generators[j]; 52 | assert(g[i] >= i); 53 | if (g[i] == i) 54 | continue; 55 | else if (posByFirst[g[i]] == -1) { 56 | posByFirst[g[i]] = pt; 57 | g.swap(generators[pt]); 58 | pt++; 59 | } else { 60 | g = inv(generators[posByFirst[g[i]]]) * g; 61 | } 62 | } 63 | } 64 | assert(pt <= n * (n - 1) / 2); 65 | generators.resize(pt); 66 | } 67 | 68 | llong calc(vector generators) { 69 | if (generators.empty()) 70 | return 1ll; 71 | int n = generators.front().size(); 72 | if (n == 0) 73 | return 1ll; 74 | 75 | vector sigma(n, perm()); 76 | DFS(identity(n), generators, sigma); 77 | vector invSigma(n, perm()); 78 | for (int i = 0; i < n; i++) 79 | invSigma[i] = inv(sigma[i]); 80 | 81 | int nSigma = 0; 82 | 83 | vector newGenerators; 84 | for (int i = 0; i < n; i++) { 85 | if (sigma[i].empty()) 86 | continue; 87 | nSigma++; 88 | for (const perm& g : generators) { 89 | perm x = g * sigma[i]; 90 | assert(!invSigma[x[0]].empty()); 91 | newGenerators.emplace_back(invSigma[x[0]] * x); 92 | } 93 | } 94 | 95 | reduceGenerators(newGenerators); 96 | for (perm& g : newGenerators) { 97 | assert(g[0] == 0); 98 | g.erase(g.begin() + 0); 99 | for (int& x : g) 100 | --x; 101 | } 102 | 103 | return nSigma * calc(newGenerators); 104 | } 105 | 106 | 107 | int main() { 108 | int k, n; 109 | scanf("%d %d", &k, &n); 110 | vector generators; 111 | for (int i = 0; i < k; i++) { 112 | perm x(n); 113 | for (int j = 0; j < n; j++) 114 | scanf("%d", &x[j]), --x[j]; 115 | generators.emplace_back(x); 116 | } 117 | llong ans = calc(generators); 118 | printf("%lld\n", ans); 119 | return 0; 120 | } 121 | -------------------------------------------------------------------------------- /Math/SegmentSieve.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #define MAXL 1000005 3 | #define MAXSQRTB 47000 4 | #define INF 1000000000 5 | using namespace std; 6 | typedef long long ll; 7 | bool is_prime_small[MAXSQRTB]; 8 | bool is_prime[MAXL]; 9 | vector prime; 10 | void segment_sieve(ll a,ll b) 11 | { 12 | for(ll i=0;(ll)i*i<=b;i++) is_prime_small[i]=true; 13 | for(ll i=0;i 2 | using namespace std; 3 | double simpson(double a,double b) 4 | { 5 | double c=a+(b-a)/2; 6 | return (F(a)+4*F(c)+F(b))*(b-a)/6; 7 | } 8 | double asr(double a,double b,double eps,double A) 9 | { 10 | double c=a+(b-a)/2; 11 | double L=simpson(a,c),R=simpson(c,b); 12 | if(fabs(L+R-A)<=15*eps) return L+R+(L+R-A)/15.0; 13 | return asr(a,c,eps/2,L)+asr(c,b,eps/2,R); 14 | } 15 | double asr(double a,double b,double eps) 16 | { 17 | return asr(a,b,eps,simpson(a,b)); 18 | } 19 | -------------------------------------------------------------------------------- /Math/StirlingI.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #define MAXN 500005 3 | #define MOD 998244353 4 | #define INF 1000000000 5 | #define F first 6 | #define S second 7 | using namespace std; 8 | typedef long long ll; 9 | typedef pair P; 10 | const int g=3; 11 | int tot=1; 12 | int dbit(int x) 13 | { 14 | while((x&-x)!=x) x+=x&-x; 15 | return x; 16 | } 17 | int two[32]; 18 | int pow_mod(int a,int i) 19 | { 20 | if(i==0) return 1; 21 | int s=1; 22 | while(i>0) 23 | { 24 | if(i&1) s=(1LL*s*a)%MOD; 25 | a=(1LL*a*a)%MOD; 26 | i>>=1; 27 | } 28 | return s; 29 | } 30 | int rev(int x,int r) 31 | { 32 | int ans=0; 33 | for(int i=0;i1) {cnt++; t/=2;} 41 | for(;;r++) if((1<=MOD) A[k+j]-=MOD; 61 | A[k+j+m/2]=u+MOD-t; 62 | if(A[k+j+m/2]>=MOD) A[k+j+m/2]-=MOD; 63 | w=1LL*w*wn%MOD; 64 | } 65 | } 66 | } 67 | if(on==-1) 68 | { 69 | for(int i=1;ir){ C[++tot]=1; return (atom){tot,tot};} 83 | if (l==r){ C[++tot]=l; C[++tot]=1; return (atom){tot-1,tot};} 84 | int mid=(l+r)/2; atom k1=solve(l,mid),k2=solve(mid+1,r); 85 | int n=max(mid-l+1,r-mid),sz=1; 86 | while (sz<=(n<<1)) sz*=2; 87 | for (int i=0;i 2 | #define MAXN 100005 3 | #define MOD 998244353 4 | #define INF 1000000000 5 | #define F first 6 | #define S second 7 | using namespace std; 8 | typedef long long ll; 9 | typedef pair P; 10 | const int g=3; 11 | int two[32]; 12 | int dbit(int x) 13 | { 14 | while((x&-x)!=x) x+=x&-x; 15 | return x; 16 | } 17 | int pow_mod(int a,int i) 18 | { 19 | if(i==0) return 1; 20 | int s=1; 21 | while(i>0) 22 | { 23 | if(i&1) s=(1LL*s*a)%MOD; 24 | a=(1LL*a*a)%MOD; 25 | i>>=1; 26 | } 27 | return s; 28 | } 29 | int rev(int x,int r) 30 | { 31 | int ans=0; 32 | for(int i=0;i1) {cnt++; t/=2;} 40 | for(;;r++) if((1<=MOD) A[k+j]-=MOD; 60 | A[k+j+m/2]=u+MOD-t; 61 | if(A[k+j+m/2]>=MOD) A[k+j+m/2]-=MOD; 62 | w=1LL*w*wn%MOD; 63 | } 64 | } 65 | } 66 | if(on==-1) 67 | { 68 | for(int i=1;i 2 | #define MAXN 100005 3 | #define INF 1000000000 4 | #define MOD 1000000007 5 | #define F first 6 | #define S second 7 | using namespace std; 8 | typedef long long ll; 9 | typedef pair P; 10 | int fact[MAXN]; 11 | int pow_mod(int a,int i) 12 | { 13 | if(i==0) return 1; 14 | int s=1; 15 | while(i>0) 16 | { 17 | if(i&1) s=(1LL*s*a)%MOD; 18 | a=(1LL*a*a)%MOD; 19 | i>>=1; 20 | } 21 | return s; 22 | } 23 | int inv(int x) 24 | { 25 | return pow_mod(x,MOD-2); 26 | } 27 | int n,m; 28 | int main() 29 | { 30 | scanf("%d%d",&n,&m); 31 | fact[0]=1; 32 | for(int i=1;i<=n;i++) 33 | fact[i]=1LL*fact[i-1]*i%MOD; 34 | int ans=0; 35 | for(int k=0;k<=m;k++) 36 | { 37 | int res=((1LL*fact[m]*inv(fact[k])%MOD)*inv(fact[m-k])%MOD)*pow_mod(m-k,n)%MOD; 38 | if(!(k&1)) ans=(ans+res)%MOD; else ans=(ans+MOD-res)%MOD; 39 | } 40 | ans=1LL*ans*(inv(fact[m]))%MOD; 41 | printf("%d\n",ans); 42 | } -------------------------------------------------------------------------------- /Math/SubsetConvolution.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #define MAXN 2000005 3 | #define MAXLOGN 22 4 | #define INF 1000000000 5 | #define MOD 1000000007 6 | #define F first 7 | #define S second 8 | using namespace std; 9 | typedef long long ll; 10 | typedef pair P; 11 | int f[MAXN],g[MAXN]; 12 | int fhat[MAXLOGN][MAXN],ghat[MAXLOGN][MAXN],h[MAXLOGN][MAXN]; 13 | int fog[MAXN]; 14 | int n; 15 | void add(int &a,int b) {a+=b; if(a>=MOD) a-=MOD;} 16 | void dec(int &a,int b) {a-=b; if(a<0) a+=MOD;} 17 | void subset_convolution() 18 | { 19 | 20 | for(int mask=0;mask<(1< 2 | #define MAXN 5000005 3 | #define INF 1000000000 4 | #define MOD 1000000007 5 | #define F first 6 | #define S second 7 | using namespace std; 8 | typedef long long ll; 9 | typedef pair P; 10 | bool is_prime[MAXN]; 11 | int cnt,miu[MAXN],prime[MAXN]; 12 | ll n,m,f[MAXN]; 13 | map mp; 14 | void genmiu(int n) 15 | { 16 | int p=0; 17 | for(int i=0;i<=n;i++) is_prime[i]=true; 18 | is_prime[0]=is_prime[1]=false; 19 | memset(miu,0,sizeof(miu)); 20 | miu[1]=1; 21 | for(int i=2;i<=n;i++) 22 | { 23 | if(is_prime[i]) {prime[p++]=i; miu[i]=-1;} 24 | for(int j=0;jn) break; 27 | is_prime[prime[j]*i]=false; 28 | miu[i*prime[j]]=i%prime[j]?-miu[i]:0; 29 | if(i%prime[j]==0) break; 30 | } 31 | } 32 | for(int i=1;i<=n;i++) f[i]=f[i-1]+miu[i]; 33 | } 34 | ll calc(ll x) 35 | { 36 | if(x<=5000000) return f[x]; 37 | if(mp.find(x)!=mp.end()) return mp[x]; 38 | ll ans=1; 39 | for(ll i=2,r;i<=x;i=r+1) 40 | { 41 | r=x/(x/i); 42 | ans-=calc(x/i)*(r-i+1); 43 | } 44 | return mp[x]=ans; 45 | } 46 | int main() 47 | { 48 | genmiu(5000000); 49 | scanf("%lld%lld",&n,&m); 50 | printf("%lld\n",calc(m)-calc(n-1)); 51 | return 0; 52 | } 53 | -------------------------------------------------------------------------------- /Math/SumPhi.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #define MAXN 5000005 3 | #define INF 1000000000 4 | #define MOD 1000000007 5 | #define F first 6 | #define S second 7 | using namespace std; 8 | typedef long long ll; 9 | typedef pair P; 10 | bool is_prime[MAXN]; 11 | ll cnt,phi[MAXN],prime[MAXN]; 12 | ll n,f[MAXN]; 13 | map mp; 14 | ll mul_mod(ll a,ll i) 15 | { 16 | ll s=0;a%=MOD; 17 | while(i) 18 | { 19 | if(i&1) s=(s+a)%MOD; 20 | a=(a+a)%MOD; 21 | i>>=1; 22 | } 23 | return s; 24 | } 25 | 26 | ll pow_mod(ll a,ll i) 27 | { 28 | ll s=1; 29 | while(i) 30 | { 31 | if(i&1) s=mul_mod(s,a); 32 | a=mul_mod(a,a); 33 | i>>=1; 34 | } 35 | return s; 36 | } 37 | void genphi(ll n) 38 | { 39 | ll p=0; 40 | memset(phi,0,sizeof(phi)); 41 | phi[1]=1; 42 | for(ll i=0;i<=n;i++) is_prime[i]=true; 43 | is_prime[0]=is_prime[1]=false; 44 | for(ll i=2;i<=n;i++) 45 | { 46 | if(is_prime[i]) {prime[p++]=i; phi[i]=i-1;} 47 | for(ll j=0;jn) break; 50 | is_prime[prime[j]*i]=false; 51 | phi[i*prime[j]]=phi[i]*(i%prime[j]?prime[j]-1:prime[j]); 52 | if(i%prime[j]==0) break; 53 | } 54 | } 55 | for(ll i=1;i<=n;i++) f[i]=(f[i-1]+phi[i])%MOD; 56 | } 57 | ll calc(ll x) 58 | { 59 | if(x<=5000000) return f[x]; 60 | if(mp.find(x)!=mp.end()) return mp[x]; 61 | ll ans=mul_mod(mul_mod(x,x+1),pow_mod(2,MOD-2)); 62 | for(ll i=2,r;i<=x;i=r+1) 63 | { 64 | r=x/(x/i); 65 | ans=(ans-calc(x/i)*((r-i+1)%MOD)%MOD+MOD)%MOD; 66 | } 67 | return mp[x]=ans; 68 | } 69 | int main() 70 | { 71 | genphi(5000000); 72 | scanf("%lld",&n); 73 | printf("%lld\n",calc(n)); 74 | return 0; 75 | } 76 | -------------------------------------------------------------------------------- /Math/TonelliShanks.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #define MAXN 100005 3 | #define INF 1000000000 4 | #define MOD 1000000007 5 | #define F first 6 | #define S second 7 | using namespace std; 8 | typedef long long ll; 9 | typedef pair P; 10 | int n,k,a[MAXN]; 11 | ll pow_mod(ll a,ll i,ll m) 12 | { 13 | ll s=1; 14 | while(i) 15 | { 16 | if(i&1) s=s*a%m; 17 | a=a*a%m; 18 | i>>=1; 19 | } 20 | return s; 21 | } 22 | ll Tonelli_Shanks(ll n,ll p) 23 | { 24 | if(p==2) return (n&1)?1:-1; 25 | if(pow_mod(n,p>>1,p)!=1) return -1; 26 | if(p&2) return pow_mod(n,(p+1)>>2,p); 27 | int s=__builtin_ctzll(p^1); 28 | ll q=p>>s,z=2; 29 | for(;pow_mod(z,p>>1,p)==1;++z); 30 | ll c=pow_mod(z,q,p),r=pow_mod(n,(q+1)>>1,p),t=pow_mod(n,q,p),tmp; 31 | for(int m=s,i;t!=1;) 32 | { 33 | for(i=0,tmp=t;tmp!=1;++i) tmp=tmp*tmp%p; 34 | for(;i<--m;) c=c*c%p; 35 | r=r*c%p;c=c*c%p;t=t*c%p; 36 | } 37 | return r; 38 | } 39 | int main() 40 | { 41 | ll n,p; 42 | while(scanf("%lld%lld",&n,&p)==2) printf("%lld\n",Tonelli_Shanks(n,p)); 43 | return 0; 44 | } 45 | 46 | -------------------------------------------------------------------------------- /Others/ConvexHullTrick.cpp: -------------------------------------------------------------------------------- 1 | #pragma GCC optimize(3) 2 | #include 3 | #define MAXN 100005 4 | #define INF 1000000000 5 | #define MOD 1000000007 6 | #define F first 7 | #define S second 8 | using namespace std; 9 | typedef long long ll; 10 | typedef pair P; 11 | ll N,tot,t,now; 12 | P st[MAXN]; 13 | void add(ll u,ll v) 14 | { 15 | P p=P(u,v); 16 | while(t-now>1&&(st[t-1].F-st[t-2].F)*(p.S-st[t-1].S)<=(st[t-1].F-p.F)*(st[t-2].S-st[t-1].S)) t--; 17 | st[t++]=p; 18 | } 19 | bool cmp(P x,P y) 20 | { 21 | if(x.S!=y.S) return x.S1) 28 | { 29 | ll mid=(l+r)/2; 30 | if(st[mid].F*x+st[mid].S<=st[mid+1].F*x+st[mid+1].S) l=mid; 31 | else r=mid; 32 | } 33 | return st[r].F*x+st[r].S; 34 | } 35 | int main() 36 | { 37 | } 38 | -------------------------------------------------------------------------------- /Others/DynamicConvexHullTrick.cpp: -------------------------------------------------------------------------------- 1 | #pragma GCC optimize(3) 2 | #include 3 | #define MAXN 100005 4 | #define INF 1000000000 5 | #define MOD 1000000007 6 | #define F first 7 | #define S second 8 | using namespace std; 9 | typedef long long ll; 10 | typedef pair P; 11 | int n,k,a[MAXN]; 12 | bool qu=0; 13 | struct line 14 | { 15 | long long m,b; 16 | mutable function succ; 17 | bool operator<(const line& rhs) const 18 | { 19 | if (!qu) return mbm-m); 24 | } 25 | }; 26 | struct hull:public multiset 27 | { 28 | bool bad(iterator y) 29 | { 30 | auto z=next(y); 31 | if (y==begin()) 32 | { 33 | if (z==end()) 34 | return 0; 35 | return (y->m==z->m && y->b<=z->b); 36 | } 37 | auto x=prev(y); 38 | if (z==end()) 39 | return (y->m==x->m && y->b<=x->b); 40 | return 1.0*(x->b-y->b)*(z->m-y->m)>=1.0*(y->b-z->b)*(y->m-x->m); 41 | } 42 | void add(long long m,long long b) 43 | { 44 | auto it=insert({m,b}); 45 | it->succ=[=] { return (next(it)==end())? 0:&*next(it); }; 46 | if (bad(it)) 47 | { 48 | erase(it); 49 | return; 50 | } 51 | while (next(it)!=end() && bad(next(it))) erase(next(it)); 52 | while (it!=begin() && bad(prev(it))) erase(prev(it)); 53 | } 54 | long long eval(long long x) 55 | { 56 | if (empty()) return -(1LL<<60); 57 | qu=1;line l=*lower_bound((line){x,0});qu=0; 58 | return l.m*x+l.b; 59 | } 60 | }; 61 | int main() 62 | { 63 | return 0; 64 | } 65 | 66 | -------------------------------------------------------------------------------- /Others/DynamicDP.cpp: -------------------------------------------------------------------------------- 1 | //luogu 4719 dynamic maximum weight vertex cover 2 | #pragma GCC optimize(3) 3 | #include 4 | #define MAXN 100005 5 | #define INF 1000000000 6 | #define MOD 1000000007 7 | #define F first 8 | #define S second 9 | using namespace std; 10 | typedef long long ll; 11 | typedef pair P; 12 | int tot,n,q; 13 | int dp[MAXN][2]; 14 | int ldp[MAXN][2]; 15 | int pa[MAXN],a[MAXN],dep[MAXN],sz[MAXN],wson[MAXN],top[MAXN],st[MAXN],ed[MAXN],tpos[MAXN],w[MAXN],bot[MAXN]; 16 | struct mat 17 | { 18 | int v[2][2]; 19 | mat(){v[0][0]=v[0][1]=v[1][0]=v[1][1]=-INF;} 20 | }; 21 | mat mul(mat a,mat b) 22 | { 23 | mat c; 24 | for(int i=0;i<2;i++) 25 | for(int j=0;j<2;j++) 26 | for(int k=0;k<2;k++) 27 | c.v[i][j]=max(c.v[i][j],a.v[i][k]+b.v[k][j]); 28 | return c; 29 | } 30 | mat unit; 31 | vector G[MAXN]; 32 | void dfs1(int v,int p,int d) 33 | { 34 | dep[v]=d;pa[v]=p;sz[v]=1; 35 | for(int i=0;i<(int)G[v].size();i++) 36 | { 37 | int to=G[v][i]; 38 | if(to==p) continue; 39 | dfs1(to,v,d+1); 40 | if(sz[to]>sz[wson[v]]) wson[v]=to; 41 | sz[v]+=sz[to]; 42 | } 43 | } 44 | void dfs2(int v,int p,int num) 45 | { 46 | top[v]=num; bot[num]=v; 47 | st[v]=++tot; 48 | tpos[tot]=v; 49 | if(wson[v]) dfs2(wson[v],v,num); 50 | for(int i=0;i<(int)G[v].size();i++) 51 | { 52 | int to=G[v][i]; 53 | if(to==p||to==wson[v]) continue; 54 | dfs2(to,v,to); 55 | } 56 | ed[v]=tot; 57 | } 58 | struct segtree 59 | { 60 | mat val[4*MAXN]; 61 | void pushup(int k) 62 | { 63 | val[k]=mul(val[k*2],val[k*2+1]); 64 | } 65 | void build(int k,int l,int r) 66 | { 67 | if(l==r) 68 | { 69 | int v=tpos[l]; 70 | val[k].v[0][0]=val[k].v[0][1]=ldp[v][0]; 71 | val[k].v[1][0]=ldp[v][1]; 72 | val[k].v[1][1]=-INF; 73 | return; 74 | } 75 | int mid=(l+r)/2; 76 | build(k*2,l,mid); build(k*2+1,mid+1,r); 77 | pushup(k); 78 | } 79 | void update(int k,int l,int r,int p,int v1,int v2) 80 | { 81 | if(l==r) 82 | { 83 | val[k].v[0][0]=val[k].v[0][1]=v1; 84 | val[k].v[1][0]=v2; 85 | val[k].v[1][1]=-INF; 86 | return; 87 | } 88 | int mid=(l+r)/2; 89 | if(p<=mid) update(k*2,l,mid,p,v1,v2); 90 | else update(k*2+1,mid+1,r,p,v1,v2); 91 | pushup(k); 92 | } 93 | mat query(int k,int l,int r,int x,int y) 94 | { 95 | if(x>r||l>y) return unit; 96 | if(l>=x&&r<=y) return val[k]; 97 | int mid=(l+r)/2; 98 | return mul(query(k*2,l,mid,x,y),query(k*2+1,mid+1,r,x,y)); 99 | } 100 | }tree; 101 | void init() 102 | { 103 | tot=0; 104 | memset(wson,0,sizeof(wson));//important when multiple test cases!!! 105 | dfs1(1,0,1); 106 | dfs2(1,0,1); 107 | tree.build(1,1,n); 108 | } 109 | void update(int v,int x) 110 | { 111 | ldp[v][1]+=(x-w[v]); w[v]=x; 112 | while(v!=0) 113 | { 114 | int l=st[top[v]],r=st[bot[top[v]]]; 115 | //mat tmp1(2,vec(1)),tmp2(2,vec(1)); 116 | //tmp1[0][0]=tmp1[1][0]=tmp2[0][0]=tmp2[1][0]=0; 117 | mat past=tree.query(1,1,n,l,r); 118 | tree.update(1,1,n,st[v],ldp[v][0],ldp[v][1]); 119 | mat now=tree.query(1,1,n,l,r); 120 | v=pa[top[v]]; 121 | ldp[v][0]+=max(now.v[0][0],now.v[1][0])-max(past.v[0][0],past.v[1][0]); 122 | ldp[v][1]+=now.v[0][0]-past.v[0][0]; 123 | } 124 | } 125 | int main() 126 | { 127 | unit.v[0][0]=unit.v[1][1]=0; unit.v[0][1]=unit.v[1][0]=-INF; 128 | scanf("%d%d",&n,&q); 129 | for(int i=1;i<=n;i++) scanf("%d",&a[i]); 130 | for(int i=0;i 2 | #define MAXN 1005 3 | #define MAXV 500005 4 | #define MAXE 1000005 5 | #define INF 1000000000 6 | using namespace std; 7 | typedef long long ll; 8 | typedef pair P; 9 | int n,m,sz,a[MAXN],ans[MAXN]; 10 | vector g[MAXN]; 11 | vector dis; 12 | struct edge{int to,cap,rev;}; 13 | int V; 14 | vector G[MAXN]; 15 | bool valid[MAXN],good[MAXN],vis[MAXN]; 16 | int level[MAXN]; 17 | int iter[MAXN]; 18 | void add_edge(int from,int to,int cap) 19 | { 20 | G[from].push_back((edge){to,cap,(int)G[to].size()}); 21 | G[to].push_back((edge){from,0,(int)G[from].size()-1}); 22 | } 23 | void bfs(int s) 24 | { 25 | memset(level,-1,sizeof(level)); 26 | queue que; 27 | level[s]=0; 28 | que.push(s); 29 | while(!que.empty()) 30 | { 31 | int v=que.front(); que.pop(); 32 | for(int i=0;i<(int)G[v].size();i++) 33 | { 34 | edge &e=G[v][i]; 35 | if(e.cap>0&&level[e.to]<0) 36 | { 37 | level[e.to]=level[v]+1; 38 | que.push(e.to); 39 | } 40 | } 41 | } 42 | } 43 | 44 | int dfs(int v,int t,int f) 45 | { 46 | if(v==t) return f; 47 | for(int &i=iter[v];i<(int)G[v].size();i++) 48 | { 49 | edge &e=G[v][i]; 50 | if(level[v]0) 51 | { 52 | int d=dfs(e.to,t,min(f,e.cap)); 53 | if(d>0) 54 | { 55 | e.cap-=d; 56 | G[e.to][e.rev].cap+=d; 57 | return d; 58 | } 59 | } 60 | } 61 | return 0; 62 | } 63 | int max_flow(int s,int t) 64 | { 65 | int flow=0; 66 | for(;;) 67 | { 68 | bfs(s); 69 | if(level[t]<0) return flow; 70 | memset(iter,0,sizeof(iter)); 71 | int f; 72 | while((f=dfs(s,t,INF))>0) 73 | flow+=f; 74 | } 75 | } 76 | void dfs2(int v) 77 | { 78 | vis[v]=true; 79 | if(v!=n+1||v!=n+2) good[v]=true; 80 | for(auto e:G[v]) 81 | { 82 | if(e.cap==0) continue; 83 | if(!vis[e.to]) dfs2(e.to); 84 | } 85 | } 86 | void solve(int l,int r,vector &v) 87 | { 88 | if(!v.size()) return; 89 | if(l==r) 90 | { 91 | for(auto x:v) ans[x]=dis[l]; 92 | return; 93 | } 94 | int mid=(l+r)/2; 95 | for(auto x:v) G[x].clear(),valid[x]=true,good[x]=false,vis[x]=false; 96 | int s=n+1,t=n+2; 97 | G[s].clear(); G[t].clear(); 98 | for(auto x:v) 99 | { 100 | int cost; 101 | if(a[x]>=dis[mid+1]) cost=1; else cost=-1; 102 | if(cost>=0) add_edge(s,x,1); else add_edge(x,t,1); 103 | for(auto to:g[x]) if(valid[to]) add_edge(x,to,INF); 104 | } 105 | vector lhs,rhs; 106 | max_flow(s,t); 107 | dfs2(s); 108 | for(auto x:v) if(good[x]) rhs.push_back(x); else lhs.push_back(x); 109 | for(auto x:v) valid[x]=false; 110 | solve(l,mid,lhs); solve(mid+1,r,rhs); 111 | } 112 | int main() 113 | { 114 | scanf("%d%d",&n,&m); 115 | for(int i=1;i<=n;i++) 116 | { 117 | scanf("%d",&a[i]); 118 | dis.push_back(a[i]); 119 | } 120 | sort(dis.begin(),dis.end()); 121 | dis.erase(unique(dis.begin(),dis.end()),dis.end()); 122 | for(int i=0;i v; 130 | for(int i=1;i<=n;i++) v.push_back(i); 131 | solve(0,sz-1,v); 132 | for(int i=1;i<=n;i++) printf("%d ",ans[i]); 133 | return 0; 134 | } 135 | -------------------------------------------------------------------------------- /Others/Knuth.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #define MAXN 2005 3 | #define INF 1000000000 4 | using namespace std; 5 | typedef long long ll; 6 | ll a[MAXN]; 7 | ll n,k; 8 | ll dp[MAXN][MAXN],knuth[MAXN][MAXN]; 9 | int main() 10 | { 11 | while(scanf("%lld %lld",&n,&k)==2) 12 | { 13 | a[0]=0; 14 | for(ll i=1;i<=k;i++) 15 | scanf("%lld",&a[i]); 16 | a[k+1]=n; 17 | for(ll i=0;i<=k+1;i++) 18 | for(ll j=0;j<=k+1;j++) 19 | dp[i][j]=INF; 20 | for(ll i=0;i<=k;i++) 21 | dp[i][i+1]=0; 22 | for(ll l=3;l<=k+2;l++) 23 | for(ll i=0;i<=k+2-l;i++) 24 | { 25 | if(l==3) 26 | { 27 | dp[i][i+l-1]=a[i+l-1]-a[i]; 28 | knuth[i][i+l-1]=i+1; 29 | } 30 | else 31 | for(ll j=knuth[i][i+l-2];j<=knuth[i+1][i+l-1];j++) 32 | if(dp[i][j]+dp[j][i+l-1]+a[i+l-1]-a[i] 2 | #define MAXN 100005 3 | int w[MAXN],v[MAXN],m[MAXN]; 4 | int dp[MAXW+1]; 5 | int deq[MAXW+1]; 6 | int deqv[MAXW+1]; 7 | void solve() 8 | { 9 | for(int i=0;i 2 | #define MAXN 100005 3 | #define INF 1000000000 4 | #define MOD 1000000007 5 | #define F first 6 | #define S second 7 | using namespace std; 8 | typedef long long ll; 9 | typedef pair P; 10 | int n,sg[2][2]={0,0,0,1}; 11 | int nim_mult_pow(int x,int y) 12 | { 13 | if(x<2) 14 | return sg[x][y]; 15 | int a=0; 16 | for(;;a++) 17 | if(x>=(1<<(1<=(1<<(1< 3 | vector smawck(F f, const std::vector &rows, const std::vector &cols) 4 | { 5 | std::vector ans(rows.size(), -1); 6 | if((int) std::max(rows.size(), cols.size()) <= 2) 7 | { 8 | for(int i = 0; i < (int) rows.size(); i++) 9 | { 10 | for(auto j : cols) 11 | if(ans[i] == -1 || f(rows[i], ans[i], j)) 12 | ans[i] = j; 13 | } 14 | } else if(rows.size() < cols.size()) { 15 | // reduce 16 | vector st; 17 | for(int j : cols) { 18 | while(1) { 19 | if(st.empty()) { 20 | st.push_back(j); 21 | break; 22 | } else if(f(rows[(int) st.size() - 1], st.back(), j)) { 23 | st.pop_back(); 24 | } else if(st.size() < rows.size()) { 25 | st.push_back(j); 26 | break; 27 | } else { 28 | break; 29 | } 30 | } 31 | } 32 | ans = smawck(f, rows, st); 33 | } else { 34 | std::vector newRows; 35 | for(int i = 1; i < (int) rows.size(); i += 2) { 36 | newRows.push_back(rows[i]); 37 | } 38 | auto otherAns = smawck(f, newRows, cols); 39 | for(int i = 0; i < (int) newRows.size(); i++) { 40 | ans[2*i+1] = otherAns[i]; 41 | } 42 | for(int i = 0, l = 0, r = 0; i < (int) rows.size(); i += 2) { 43 | while(l && cols[l-1] >= ans[i-1]) l--; 44 | if(i+1 == (int) rows.size()) r = (int) cols.size(); 45 | while(r < (int) cols.size() && r <= ans[i+1]) r++; 46 | ans[i] = cols[l++]; 47 | for(; l < r; l++) { 48 | if(f(rows[i], ans[i], cols[l])) { 49 | ans[i] = cols[l]; 50 | } 51 | } 52 | l--; 53 | } 54 | } 55 | return ans; 56 | } 57 | 58 | // max smawck 59 | // F(i, j, k) checks if M[i][j] <= M[i][k] 60 | // another interpretations is: 61 | // F(i, j, k) checks if M[i][k] is at least as good as M[i][j] 62 | // higher == better 63 | // when comparing 2 columns as vectors 64 | // for j < k, column j can start better than column k 65 | // as soon as column k is at least as good, it's always at least as good 66 | template 67 | std::vector smawck(F f, int n, int m) { 68 | std::vector rows(n), cols(m); 69 | for(int i = 0; i < n; i++) rows[i] = i; 70 | for(int i = 0; i < m; i++) cols[i] = i; 71 | return smawck(f, rows, cols); 72 | } 73 | 74 | template 75 | std::vector MaxConvolutionWithConvexShape(std::vector anyShape, const std::vector &convexShape) { 76 | if((int) convexShape.size() <= 1) return anyShape; 77 | if(anyShape.empty()) anyShape.push_back(0); 78 | int n = (int) anyShape.size(), m = (int) convexShape.size(); 79 | auto function = [&](int i, int j) { 80 | return anyShape[j] + convexShape[i-j]; 81 | }; 82 | auto comparator = [&](int i, int j, int k) { 83 | if(i < k) return false; 84 | if(i - j >= m) return true; 85 | return function(i, j) <= function(i, k); 86 | }; 87 | const std::vector best = smawck(comparator, n + m - 1, n); 88 | std::vector ans(n + m - 1); 89 | for(int i = 0; i < n + m - 1; i++) { 90 | ans[i] = function(i, best[i]); 91 | } 92 | return ans; 93 | } -------------------------------------------------------------------------------- /Others/SOS.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #define MAXN 100005 3 | #define INF 1000000000 4 | #define MOD 1000000007 5 | #define F first 6 | #define S second 7 | using namespace std; 8 | typedef long long ll; 9 | typedef pair P; 10 | int n,a[MAXN],f[MAXN]; 11 | int main() 12 | { 13 | scanf("%d",&n); 14 | for(int i=0;i<(1< 2 | #define MAXN 105 3 | #define MAXM 105 4 | #define INF 1000000000 5 | #define MOD 1000000007 6 | #define F first 7 | #define S second 8 | using namespace std; 9 | typedef long long ll; 10 | typedef pair P; 11 | typedef double db; 12 | typedef vector vec; 13 | typedef vector mat; 14 | //usage: 15 | //maximize cx, where x is a vector of length n, with m constraints 16 | //feed in m+1 lines 17 | //first line contains (0,c) 18 | //each of the next lines describe an inequality ax<=b in the form of (b,a) 19 | const db eps=1e-8; 20 | bool eq(db a,db b) 21 | { 22 | return fabs(a-b) vct; 41 | for(int j=0;j<=m;j++) 42 | { 43 | a[x][j]/=k; 44 | if(!eq(a[x][j],0)) vct.push_back(j); 45 | } 46 | for(int i=0;i<=n;i++) 47 | { 48 | if(eq(a[i][y],0)||i==x) continue; 49 | db coef=a[i][y]; 50 | a[i][y]=0; 51 | for(int j:vct) a[i][j]-=coef*a[x][j]; 52 | } 53 | }; 54 | while(1) 55 | { 56 | int x=-1; 57 | for(int i=1;i<=n;i++) if(ls(a[i][0],0)&&(x==-1||a[i][0]a[0][y])) y=j; 68 | if(y==-1) break; 69 | int x=-1; 70 | for(int i=1;i<=n;i++) if(ls(0,a[i][y])&&(x==-1||a[i][0]/a[i][y] ans(m+1); 75 | for(int i=1;i<=n;i++) if(left[i]<=m) ans[left[i]]=a[i][0]; 76 | ans[0]=-a[0][0]; 77 | return ans; 78 | } 79 | -------------------------------------------------------------------------------- /Others/SlopeTrick.cpp: -------------------------------------------------------------------------------- 1 | template< typename T > 2 | struct SlopeTrick 3 | { 4 | const T INF = numeric_limits::max()/3; 5 | T min_f; 6 | priority_queue,less > L; 7 | priority_queue,greater > R; 8 | T add_l,add_r; 9 | void push_R(const T& a) 10 | { 11 | R.push(a-add_r); 12 | } 13 | T top_R() const 14 | { 15 | if (R.empty()) return INF; 16 | else return R.top() + add_r; 17 | } 18 | T pop_R() 19 | { 20 | T val=top_R(); 21 | if(not R.empty()) R.pop(); 22 | return val; 23 | } 24 | void push_L(const T& a) 25 | { 26 | L.push(a-add_l); 27 | } 28 | T top_L() const 29 | { 30 | if (L.empty()) return -INF; 31 | else return L.top()+add_l; 32 | } 33 | T pop_L() 34 | { 35 | T val=top_L(); 36 | if (not L.empty()) L.pop(); 37 | return val; 38 | } 39 | size_t size() 40 | { 41 | return L.size()+R.size(); 42 | } 43 | 44 | SlopeTrick():min_f(0),add_l(0),add_r(0) {} 45 | 46 | struct Query 47 | { 48 | T lx, rx, min_f; 49 | }; 50 | 51 | // return min f(x) 52 | /*Query query() const { 53 | return (Query) { top_L(), top_R(), min_f }; 54 | }*/ 55 | 56 | // f(x) += a 57 | void add_all(const T& a) 58 | { 59 | min_f+=a; 60 | } 61 | 62 | // add \_ 63 | // f(x) += max(a - x, 0) 64 | void add_a_minus_x(const T& a) 65 | { 66 | min_f+=max(T(0),a-top_R()); 67 | push_R(a); 68 | push_L(pop_R()); 69 | } 70 | 71 | // add _/ 72 | // f(x) += max(x - a, 0) 73 | void add_x_minus_a(const T& a) 74 | { 75 | min_f+=max(T(0),top_L()-a); 76 | push_L(a); 77 | push_R(pop_L()); 78 | } 79 | 80 | // add \/ 81 | // f(x) += abs(x - a) 82 | void add_abs(const T& a) 83 | { 84 | add_a_minus_x(a); 85 | add_x_minus_a(a); 86 | } 87 | 88 | // \/ -> \_ 89 | // f_{new} (x) = min f(y) (y <= x) 90 | void clear_right() 91 | { 92 | while(not R.empty()) R.pop(); 93 | } 94 | 95 | // \/ -> _/ 96 | // f_{new} (x) = min f(y) (y >= x) 97 | void clear_left() 98 | { 99 | while(not L.empty()) L.pop(); 100 | } 101 | 102 | // \/ -> \_/ 103 | // f_{new} (x) = min f(y) (x-b <= y <= x-a) 104 | void shift(const T& a, const T& b) 105 | { 106 | assert(a<=b); 107 | add_l+=a; 108 | add_r+=b; 109 | } 110 | 111 | // \/. -> .\/ 112 | // f_{new} (x) = f(x - a) 113 | void shift(const T& a) 114 | { 115 | shift(a,a); 116 | } 117 | 118 | // L, R を破壊する 119 | T get(const T& x) 120 | { 121 | T ret=min_f; 122 | while(not L.empty()) ret+=max(T(0),pop_L()-x); 123 | while(not R.empty()) ret+=max(T(0),x-pop_R()); 124 | return ret; 125 | } 126 | 127 | void merge(SlopeTrick& st) 128 | { 129 | if(st.size()>size()) 130 | { 131 | swap(st.L,L); 132 | swap(st.R,R); 133 | swap(st.add_l,add_l); 134 | swap(st.add_r,add_r); 135 | swap(st.min_f,min_f); 136 | } 137 | while(not st.R.empty()) add_x_minus_a(st.pop_R()); 138 | while(not st.L.empty()) add_a_minus_x(st.pop_L()); 139 | min_f+=st.min_f; 140 | } 141 | }; -------------------------------------------------------------------------------- /Others/Subset.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #define MAXN 100005 3 | #define INF 1000000000 4 | #define MOD 1000000007 5 | #define F first 6 | #define S second 7 | using namespace std; 8 | typedef long long ll; 9 | typedef pair P; 10 | int n,k,a[MAXN]; 11 | void solve1(int sup)//all subsets 12 | { 13 | int sub=sup; 14 | do 15 | { 16 | //operation here 17 | sub=(sub-1)⊃ 18 | }while(sub!=sup); 19 | } 20 | void solve2(int n,int k) //all subsets of (1<>1)|y; 28 | } 29 | } 30 | int main() 31 | { 32 | return 0; 33 | } 34 | 35 | -------------------------------------------------------------------------------- /Others/SurrealNumber.cpp: -------------------------------------------------------------------------------- 1 | double getans(double l,double r) 2 | { 3 | assert(l0) return 0.0; 9 | if(l<0&&r<=0) return -getans(-r,-l); 10 | double res=1.0; 11 | while(true) 12 | { 13 | double t=0.0; 14 | while(t<=l) t+=res; 15 | if(t 2 | using namespace std; 3 | int whatday(int d,int m,int y) 4 | { 5 | int ans; 6 | if(m==1||m==2) 7 | m+=12,y--; 8 | if((y<1752)||(y==1752&&m<9)||(y==1752&&m==9&&d<3)) 9 | ans=(d+2*m+3*(m+1)/5+y+y/4+5)%7; 10 | else 11 | ans=(d+2*m+3*(m+1)/5+y+y/4-y/100+y/400)%7; 12 | return ans; 13 | } 14 | int main() 15 | { 16 | return 0; 17 | } 18 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # CodeTemplates 2 | ACM/ICPC Code Templates 3 | -------------------------------------------------------------------------------- /String/ACAM.cpp: -------------------------------------------------------------------------------- 1 | #define MAXN 50020 2 | #define MAXC 26 3 | struct aho_corasick { 4 | int cnt=0,link[MAXN],ch[MAXN][MAXC],nxt[MAXN][MAXC]; 5 | bool term[MAXN]; 6 | int top[MAXN]; 7 | void add(string &s,int c) { 8 | int cur=0; 9 | for(char &c:s) { 10 | if(ch[cur][c-'a']==0) ch[cur][c-'a']=++cnt; 11 | cur=ch[cur][c-'a']; 12 | } 13 | term[cur]=true; 14 | } 15 | void BFS() { 16 | queue q; 17 | for(q.push(0);!q.empty();q.pop()) { 18 | int u=q.front(); 19 | top[u]=(term[link[u]]?link[u]:top[link[u]]); 20 | for(int i=0;i0) { 22 | int v=ch[u][i]; 23 | q.push(v); 24 | nxt[u][i]=v; 25 | link[v]=nxt[link[u]][i]; 26 | if (link[v]==v) link[v]=0; 27 | } 28 | else nxt[u][i]=nxt[link[u]][i]; 29 | } 30 | } 31 | } 32 | } acs; -------------------------------------------------------------------------------- /String/GSAM.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #define MAXN 100005 3 | #define INF 1000000000 4 | #define MOD 1000000007 5 | #define F first 6 | #define S second 7 | using namespace std; 8 | typedef long long ll; 9 | typedef pair P; 10 | struct GSAM 11 | { 12 | vector> edges; 13 | vector link; 14 | vector length; 15 | int last; 16 | void init() 17 | { 18 | edges.clear(); link.clear(); length.clear(); 19 | edges.push_back(map()); 20 | link.push_back(-1); 21 | length.push_back(0); 22 | } 23 | int add(int p,char ch) 24 | { 25 | if(edges[p].find(ch)!=edges[p].end()) 26 | { 27 | int q=edges[p][ch]; 28 | if(length[p]+1==length[q]) return q; 29 | edges.push_back(edges[q]); 30 | length.push_back(length[p]+1); 31 | int qq=edges.size()-1; 32 | while(p>=0&&edges[p][ch]==q) 33 | { 34 | edges[p][ch]=qq; 35 | p=link[p]; 36 | } 37 | link.push_back(link[q]); link[q]=qq; 38 | return qq; 39 | } 40 | edges.push_back(map()); 41 | length.push_back(length[p]+1); link.push_back(0); 42 | int r=edges.size()-1; 43 | while(p>=0&&edges[p].find(ch)==edges[p].end()) 44 | { 45 | edges[p][ch]=r; 46 | p=link[p]; 47 | } 48 | if(p!=-1) 49 | { 50 | int q=edges[p][ch]; 51 | if(length[p]+1==length[q]) link[r]=q; 52 | else 53 | { 54 | edges.push_back(edges[q]); 55 | length.push_back(length[p]+1); 56 | link.push_back(link[q]); 57 | int qq=edges.size()-1; 58 | link[q]=qq; link[r]=qq; 59 | while(p>=0&&edges[p][ch]==q) 60 | { 61 | edges[p][ch]=qq; 62 | p=link[p]; 63 | } 64 | } 65 | } 66 | return r; 67 | } 68 | void build(string &s) 69 | { 70 | init(); 71 | int cur=0; 72 | for(int i=0;i<(int)s.size();i++) cur=add(cur,s[i]); 73 | } 74 | }; 75 | -------------------------------------------------------------------------------- /String/Hash.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #define MAXN 100005 3 | using namespace std; 4 | typedef unsigned long long ull; 5 | const ull B=1000000007; 6 | bool contain(string a,string b) 7 | { 8 | int al=a.length(),bl=b.length(); 9 | if(al>bl) return false; 10 | ull t=1; 11 | for(int i=0;i 2 | using namespace std; 3 | vector kmp(string a,string b) // a=pattern, b=text 4 | { 5 | int n=a.size(); 6 | vector next(n+1,0); 7 | for(int i=1;i0) 11 | { 12 | j=next[j]; 13 | if(a[j]==a[i]) 14 | { 15 | next[i+1]=j+1; 16 | break; 17 | } 18 | } 19 | } 20 | vector p;//p=positions 21 | int m=b.size(); 22 | for(int i=0,j=0;i0) 31 | { 32 | j=next[j]; 33 | if(b[i]==a[j]) 34 | { 35 | j++; 36 | break; 37 | } 38 | } 39 | } 40 | if(j==n) 41 | { 42 | p.push_back(i-n+1); 43 | } 44 | } 45 | return p; 46 | } 47 | int main() 48 | { 49 | return 0; 50 | } 51 | -------------------------------------------------------------------------------- /String/PAM.cpp: -------------------------------------------------------------------------------- 1 | struct PAM{ 2 | int s[MAXN],now; 3 | int nxt[MAXN][26],fail[MAXN],l[MAXN],last,tot; 4 | void clear(){ 5 | //1节点:奇数长度root 0节点:偶数长度root 6 | s[0]=l[1]=-1; 7 | fail[0] = tot = now =1; 8 | last = l[0]=0; 9 | memset(nxt[0],0,sizeof(nxt[0])); 10 | memset(nxt[1],0,sizeof(nxt[1])); 11 | } 12 | PAM(){clear();} 13 | int newnode(int len){ 14 | tot++; 15 | memset(nxt[tot],0,sizeof nxt[tot]); 16 | fail[tot]=0; 17 | l[tot]=len; 18 | return tot; 19 | } 20 | int get_fail(int x){ 21 | while (s[now-l[x]-2]!=s[now-1])x = fail[x]; 22 | return x; 23 | } 24 | void add(int ch){ 25 | s[now++] = ch; 26 | int cur = get_fail(last); 27 | if(!nxt[cur][ch]){ 28 | int tt = newnode(l[cur]+2); 29 | fail[tt] = nxt[get_fail(fail[cur])][ch]; 30 | nxt[cur][ch] = tt; 31 | } 32 | last = nxt[cur][ch]; 33 | } 34 | void init(string s){ 35 | f[0] = 1; 36 | int n = s.size(); 37 | for (int i=0;i 2 | #define MAXN 1005 3 | using namespace std; 4 | int sa[MAXN],rk[MAXN],oldrk[MAXN*2],id[MAXN],px[MAXN],c[MAXN]; 5 | string S; 6 | bool cmp(int x,int y,int w) 7 | { 8 | return oldrk[x]==oldrk[y]&&oldrk[x+w]==oldrk[y+w]; 9 | } 10 | void construct_sa(string S) 11 | { 12 | int n=S.length(); 13 | int m=130; 14 | int i,p,w; 15 | for(i=1;i<=n;i++) c[i]=0; 16 | for(i=1;i<=n;i++) ++c[rk[i]=S[i-1]]; 17 | for(i=1;i<=m;i++) c[i]+=c[i-1]; 18 | for(i=n;i>=1;i--) sa[c[rk[i]]--]=i; 19 | for(w=1;;w<<=1,m=p) { 20 | for(p=0,i=n;i>n-w;i--) id[++p]=i; 21 | for(i=1;i<=n;i++) if(sa[i]>w) id[++p]=sa[i]-w; 22 | memset(c,0,sizeof(c)); 23 | for(i=1;i<=n;i++) ++c[px[i]=rk[id[i]]]; 24 | for(i=1;i<=m;i++) c[i]+=c[i-1]; 25 | for(i=n;i>=1;i--) sa[c[px[i]]--]=id[i]; 26 | memcpy(oldrk,rk,sizeof(rk)); 27 | for(p=0,i=1;i<=n;i++) 28 | rk[sa[i]]=cmp(sa[i],sa[i-1],w)?p:++p; 29 | if(p==n){ 30 | for(int i=1;i<=n;i++) rk[i-1]=rk[i]-1;; 31 | for(int i=0;i0) h--; 46 | for(;j+h>S; 56 | n=S.size(); 57 | construct_sa(S,sa); 58 | construct_lcp(S,sa,lcp); 59 | int cnt=0; 60 | return 0; 61 | } 62 | -------------------------------------------------------------------------------- /String/SAIS.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #define MAXN 1000000 3 | #define L_TYPE 0 4 | #define S_TYPE 1 5 | using namespace std; 6 | inline bool is_lms_char(int *type, int x) { 7 | return x > 0 && type[x] == S_TYPE && type[x - 1] == L_TYPE; 8 | } 9 | inline bool equal_substring(int *S, int x, int y, int *type) { 10 | do { 11 | if (S[x] != S[y]) 12 | return false; 13 | x++, y++; 14 | } while (!is_lms_char(type, x) && !is_lms_char(type, y)); 15 | 16 | return S[x] == S[y]; 17 | } 18 | inline void induced_sort(int *S, int *SA, int *type, int *bucket, int *lbucket,int *sbucket, int n, int SIGMA) 19 | { 20 | for (int i = 0; i <= n; i++) 21 | if (SA[i] > 0 && type[SA[i] - 1] == L_TYPE) 22 | SA[lbucket[S[SA[i] - 1]]++] = SA[i] - 1; 23 | for (int i = 1; i <= SIGMA; i++) 24 | sbucket[i] = bucket[i] - 1; 25 | for (int i = n; i >= 0; i--) 26 | if (SA[i] > 0 && type[SA[i] - 1] == S_TYPE) 27 | SA[sbucket[S[SA[i] - 1]]--] = SA[i] - 1; 28 | } 29 | static int *SAIS(int *S, int length, int SIGMA) 30 | { 31 | int n = length - 1; 32 | int *type = new int[n + 1]; 33 | int *position = new int[n + 1]; 34 | int *name = new int[n + 1]; 35 | int *SA = new int[n + 1]; 36 | int *bucket = new int[SIGMA]; 37 | int *lbucket = new int[SIGMA]; 38 | int *sbucket = new int[SIGMA]; 39 | memset(bucket, 0, sizeof(int) * (SIGMA + 1)); 40 | for (int i = 0; i <= n; i++) 41 | bucket[S[i]]++; 42 | for (int i = 1; i <= SIGMA; i++) 43 | { 44 | bucket[i] += bucket[i - 1]; 45 | lbucket[i] = bucket[i - 1]; 46 | sbucket[i] = bucket[i] - 1; 47 | } 48 | type[n] = S_TYPE; 49 | for (int i = n - 1; i >= 0; i--) 50 | { 51 | if (S[i] < S[i + 1]) 52 | type[i] = S_TYPE; 53 | else if (S[i] > S[i + 1]) 54 | type[i] = L_TYPE; 55 | else 56 | type[i] = type[i + 1]; 57 | } 58 | int cnt = 0; 59 | for (int i = 1; i <= n; i++) 60 | if (type[i] == S_TYPE && type[i - 1] == L_TYPE) 61 | position[cnt++] = i; 62 | fill(SA, SA + n + 1, -1); 63 | for (int i = 0; i < cnt; i++) 64 | SA[sbucket[S[position[i]]]--] = position[i]; 65 | induced_sort(S, SA, type, bucket, lbucket, sbucket, n, SIGMA); 66 | fill(name, name + n + 1, -1); 67 | int lastx = -1, namecnt = 1; 68 | bool flag = false; 69 | for (int i = 1; i <= n; i++) 70 | { 71 | int x = SA[i]; 72 | 73 | if (is_lms_char(type, x)) { 74 | if (lastx >= 0 && !equal_substring(S, x, lastx, type)) 75 | namecnt++; 76 | if (lastx >= 0 && namecnt == name[lastx]) 77 | flag = true; 78 | 79 | name[x] = namecnt; 80 | lastx = x; 81 | } 82 | } 83 | name[n] = 0; 84 | int *S1 = new int[cnt]; 85 | int pos = 0; 86 | for (int i = 0; i <= n; i++) 87 | if (name[i] >= 0) 88 | S1[pos++] = name[i]; 89 | 90 | int *SA1; 91 | if (!flag) 92 | { 93 | SA1 = new int[cnt + 1]; 94 | for (int i = 0; i < cnt; i++) 95 | SA1[S1[i]] = i; 96 | } 97 | else 98 | SA1 = SAIS(S1, cnt, namecnt); 99 | lbucket[0] = sbucket[0] = 0; 100 | for (int i = 1; i <= SIGMA; i++) 101 | { 102 | lbucket[i] = bucket[i - 1]; 103 | sbucket[i] = bucket[i] - 1; 104 | } 105 | fill(SA, SA + n + 1, -1); 106 | for (int i = cnt - 1; i >= 0; i--) 107 | SA[sbucket[S[position[SA1[i]]]]--] = position[SA1[i]]; 108 | induced_sort(S, SA, type, bucket, lbucket, sbucket, n, SIGMA); 109 | return SA; 110 | } 111 | int main() 112 | { 113 | return 0; 114 | } 115 | -------------------------------------------------------------------------------- /String/SAM.cpp: -------------------------------------------------------------------------------- 1 | struct SAM{ 2 | vector> edges; 3 | vector link; 4 | vector length; 5 | void init(){ 6 | edges.clear(); link.clear(); length.clear(); 7 | edges.push_back(map()); 8 | link.push_back(-1); 9 | length.push_back(0); 10 | } 11 | int add(int p,char ch) { 12 | edges.push_back(map()); 13 | length.push_back(length[p]+1); link.push_back(0); 14 | int r=edges.size()-1; 15 | while(p>=0&&edges[p].find(ch)==edges[p].end()) { 16 | edges[p][ch]=r; 17 | p=link[p]; 18 | } 19 | if(p!=-1) { 20 | int q=edges[p][ch]; 21 | if(length[p]+1==length[q]) link[r]=q; 22 | else { 23 | edges.push_back(edges[q]); 24 | length.push_back(length[p]+1); 25 | link.push_back(link[q]); 26 | int qq=edges.size()-1; 27 | link[q]=qq; link[r]=qq; 28 | while(p>=0&&edges[p][ch]==q) { 29 | edges[p][ch]=qq; 30 | p=link[p]; 31 | } 32 | } 33 | } 34 | return r; 35 | } 36 | void build(string &s){ 37 | init(); 38 | int cur=0; 39 | for(int i=0;i<(int)s.size();i++) cur=add(cur,s[i]); 40 | } 41 | }; 42 | -------------------------------------------------------------------------------- /String/Trie.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #define MAXN 100005 3 | #define INF 1000000000 4 | #define MOD 1000000007 5 | #define F first 6 | #define S second 7 | using namespace std; 8 | typedef long long ll; 9 | typedef pair P; 10 | int tot=1,n; 11 | int trie[MAXN][26]; 12 | bool ed[MAXN]; 13 | void insert(char *s,int rt) 14 | { 15 | for(int i=0;s[i];i++) 16 | { 17 | int x=s[i]-'a'; 18 | if(trie[rt][x]==0) trie[rt][x]=++tot; 19 | rt=trie[rt][x]; 20 | } 21 | ed[rt]=true; 22 | } 23 | bool find(char *s,int rt) 24 | { 25 | for(int i=0;s[i];i++) 26 | { 27 | int x=s[i]-'a'; 28 | if(trie[rt][x]==0) return false; 29 | rt=trie[rt][x]; 30 | } 31 | return ed[rt]; 32 | } 33 | int main() 34 | { 35 | memset(ed,false,sizeof(ed)); 36 | return 0; 37 | } 38 | 39 | -------------------------------------------------------------------------------- /String/manacher.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #define MAXN 10000 3 | using namespace std; 4 | void manacher(char str[],int len[],int n) 5 | { 6 | len[0]=1; 7 | for(int i=1,j=0;i<(n<<1)-1;++i) 8 | { 9 | int p=i>>1,q=i-p,r=((j+1)>>1)+len[j]-1; 10 | len[i]=rlen[i]-1&&q+len[i]r) 14 | j=i; 15 | } 16 | } 17 | int a[MAXN]; 18 | char str[MAXN]; 19 | int main() 20 | { 21 | scanf("%s",str); 22 | int x=strlen(str); 23 | manacher(str,a,strlen(str)); 24 | for(int i=0;i<2*x-1;i++) 25 | printf("%d ",a[i]); 26 | } 27 | -------------------------------------------------------------------------------- /template.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wcysai/CodeTemplates/c958bbce705abaecaca57c123bc052a1eee513c4/template.pdf --------------------------------------------------------------------------------