[TOC]
假装有目录(以前就是有的)
woc明天就走了怎么这么多没写
之前写的忘得差不多了,再写遍(省选部分模板连同一些比较水的。。)。
就按分类顺序排了。另外还是Markdown好用,但可惜不能代码折叠。光改字体就好麻烦啊。。
计算几何。。
DP
斜率优化
四边形不等式优化
分治
CDQ分治✔
三维偏序:http://www.cnblogs.com/SovietPower/p/8574905.html
1 /* 2 5904kb 840ms 3 是对x,y,z都相同的元素去重,不是对z。。sb了。 4 去重后的贡献是q[p].cnt! 5 */ 6 #include <cstdio> 7 #include <cctype> 8 #include <algorithm> 9 #define gc() getchar() 10 #define lb(x) (x)&-(x) 11 const int N=1e5+5,MAXN=2e5+5; 12 13 int n,Ans[N]; 14 int read(); 15 struct Node 16 { 17 int x,y,z,cnt,ans; 18 void Init(){ 19 x=read(),y=read(),z=read(),cnt=1; 20 } 21 bool operator <(const Node &a)const{ 22 return x==a.x?(y==a.y?z<a.z:y<a.y):x<a.x; 23 } 24 }q[N],tmp[N]; 25 26 inline int read() 27 { 28 int now=0;register char c=gc(); 29 for(;!isdigit(c);c=gc()); 30 for(;isdigit(c);now=now*10+c-'0',c=gc()); 31 return now; 32 } 33 namespace BIT 34 { 35 int n,val[MAXN]; 36 inline void Add(int p,int v){ 37 while(p<=n) val[p]+=v,p+=lb(p); 38 } 39 inline int Query(int p){ 40 int res=0; 41 while(p) res+=val[p],p-=lb(p); 42 return res; 43 } 44 inline void Clear(int p){ 45 while(p<=n) 46 if(val[p]) val[p]=0,p+=lb(p); 47 else break; 48 } 49 } 50 void CDQ(int l,int r) 51 { 52 if(l<r){ 53 int m=l+r>>1; CDQ(l,m), CDQ(m+1,r); 54 int p1=l,p2=m+1,t=0; 55 while(p1<=m&&p2<=r) 56 { 57 if(q[p1].y<=q[p2].y) BIT::Add(q[p1].z,q[p1].cnt), tmp[t++]=q[p1++];//只是排y,别去管什么z。。 58 else q[p2].ans+=BIT::Query(q[p2].z), tmp[t++]=q[p2++]; 59 } 60 if(p1<=m){ 61 for(int i=l; i<p1; ++i) BIT::Clear(q[i].z); 62 while(p1<=m) tmp[t++]=q[p1++]; 63 } 64 else if(p2<=r){ 65 while(p2<=r) q[p2].ans+=BIT::Query(q[p2].z), tmp[t++]=q[p2++]; 66 for(int i=l; i<=m; ++i) BIT::Clear(q[i].z); 67 } 68 for(int i=0; i<t; ++i) q[l+i]=tmp[i]; 69 } 70 } 71 72 int main() 73 { 74 n=read(),BIT::n=read(); 75 for(int i=1; i<=n; ++i) q[i].Init(); 76 std::sort(q+1,q+1+n); 77 int cnt=1; 78 for(int i=2; i<=n; ++i) 79 if(q[i].z!=q[i-1].z||q[i].y!=q[i-1].y||q[i].x!=q[i-1].x) q[++cnt]=q[i]; 80 else ++q[cnt].cnt; 81 CDQ(1,cnt); 82 for(int i=1; i<=cnt; ++i) Ans[q[i].ans+q[i].cnt-1]+=q[i].cnt; 83 for(int i=0; i<n; ++i) printf("%d ",Ans[i]); 84 85 return 0; 86 }
点分治✔
http://www.cnblogs.com/SovietPower/p/8589571.html
1 #include <cstdio> 2 #include <cctype> 3 #include <algorithm> 4 #define gc() getchar() 5 const int N=1e4+5,S=1e7+5; 6 7 int n,m,Enum,root,Min,sz[N],H[N],to[N<<1],nxt[N<<1],val[N<<1],D[N],que[N],Q[105],Ans[105]; 8 bool vis[N],exist[S];//bitset随便用会更慢。。 9 10 inline int read() 11 { 12 int now=0;register char c=gc(); 13 for(;!isdigit(c);c=gc()); 14 for(;isdigit(c);now=now*10+c-'0',c=gc()); 15 return now; 16 } 17 inline void AddEdge(int u,int v,int w) 18 { 19 to[++Enum]=v, nxt[Enum]=H[u], val[Enum]=w, H[u]=Enum; 20 to[++Enum]=u, nxt[Enum]=H[v], val[Enum]=w, H[v]=Enum; 21 } 22 void Get_root(int x,int f,int tot) 23 { 24 int mx=0; sz[x]=1; 25 for(int v,i=H[x]; i; i=nxt[i]) 26 if(!vis[v=to[i]] && v!=f) 27 { 28 Get_root(v,x,tot), sz[x]+=sz[v]; 29 if(sz[v]>mx) mx=sz[v]; 30 } 31 mx=std::max(mx,tot-sz[x]); 32 if(mx<Min) Min=mx,root=x; 33 } 34 void DFS(int x,int f,int d) 35 { 36 D[++D[0]]=d; 37 for(int i=H[x]; i; i=nxt[i]) 38 if(!vis[to[i]] && to[i]!=f) DFS(to[i],x,d+val[i]); 39 } 40 void Calc(int x,int val) 41 { 42 D[0]=0, DFS(x,x,val); 43 for(int i=1; i<=D[0]; ++i) 44 for(int j=1; j<=m; ++j) 45 if(Q[j]>=D[i]) Ans[j]|=exist[Q[j]-D[i]]; 46 for(int i=1; i<=D[0]; ++i) 47 exist[D[i]]=1,que[++que[0]]=D[i]; 48 } 49 void Solve(int x) 50 { 51 vis[x]=1, que[0]=0, exist[0]=1/*!*/; 52 for(int i=H[x]; i; i=nxt[i]) 53 if(!vis[to[i]]) Calc(to[i],val[i]); 54 for(int i=1; i<=que[0]; ++i) exist[que[i]]=0; 55 for(int i=H[x]; i; i=nxt[i]) 56 if(!vis[to[i]]) 57 Min=N, Get_root(to[i],x,sz[to[i]]), Solve(root); 58 } 59 60 int main() 61 { 62 n=read(),m=read(); 63 for(int u,v,i=1; i<n; ++i) u=read(),v=read(),AddEdge(u,v,read()); 64 for(int i=1; i<=m; ++i) Q[i]=read(); 65 Min=N, Get_root(1,1,n), Solve(root); 66 for(int i=1; i<=m; ++i) puts(Ans[i]?"AYE":"NAY"); 67 68 return 0; 69 }
数据结构
线段树、树状数组、Trie树略
分块
树分块/块状树
Splay✔
http://www.cnblogs.com/SovietPower/p/8435011.html
1 #include <cstdio> 2 #include <cctype> 3 #include <algorithm> 4 //#define gc() getchar() 5 #define gc() (SS==TT&&(TT=(SS=IN)+fread(IN,1,MAXIN,stdin),SS==TT)?EOF:*SS++) 6 #define MAXIN 500000 7 const int N=2e5+5; 8 9 char IN[MAXIN],*SS=IN,*TT=IN; 10 inline int read() 11 { 12 int now=0,f=1;register char c=gc(); 13 for(;!isdigit(c);c=gc()) if(c=='-') f=-1; 14 for(;isdigit(c);now=now*10+c-'0',c=gc()); 15 return now*f; 16 } 17 namespace Splay 18 { 19 #define lson son[x][0] 20 #define rson son[x][1] 21 22 int root,size,fa[N],son[N][2],sz[N],t[N],cnt[N]; 23 inline void Update(int x){ 24 sz[x]=sz[lson]+sz[rson]+cnt[x]; 25 } 26 void Rotate(int x,int &k) 27 { 28 int a=fa[x],b=fa[a],l=son[a][1]==x,r=l^1; 29 if(k==a) k=x; 30 else son[b][son[b][1]==a]=x; 31 fa[a]=x, fa[x]=b, fa[son[x][r]]=a, 32 son[a][l]=son[x][r], son[x][r]=a; 33 Update(a);// Update(x); 34 } 35 void Splay(int x,int &k) 36 { 37 while(x!=k) 38 { 39 int a=fa[x],b=fa[a]; 40 if(a!=k) (son[a][1]==x^son[b][1]==a)?Rotate(x,k):Rotate(a,k); 41 Rotate(x,k); 42 } 43 Update(x); 44 } 45 void Insert(int v,int k) 46 { 47 int f=0; 48 while(t[k]!=v&&k) f=k,k=son[k][v>t[k]]; 49 if(k) ++cnt[k]; 50 else{ 51 k=++size, sz[k]=cnt[k]=1, t[k]=v, fa[k]=f; 52 if(f) son[f][v>t[f]]=k; 53 } 54 Splay(k,root); 55 } 56 void Rank(int v,int k) 57 { 58 // if(!k) return; 59 while(t[k]!=v && son[k][v>t[k]]) k=son[k][v>t[k]]; 60 Splay(k,root); 61 } 62 void Delete(int v,int k) 63 { 64 Rank(v,root); 65 if(cnt[root]>1) --cnt[root],--sz[root]; 66 else if(son[root][0]&&son[root][1]) 67 { 68 int ls=son[root][0],k=son[root][1]; 69 fa[root=k]=0; 70 while(son[k][0]) k=son[k][0]; 71 fa[ls]=k, son[k][0]=ls;// sz[k]+=sz[ls]; 72 Splay(k,root); 73 } 74 else root=son[root][0]^son[root][1],fa[root]=0; 75 } 76 int Get_Rank(int k,int x) 77 { 78 while(1) 79 { 80 if(sz[lson]<k && sz[lson]+cnt[x]>=k) return x; 81 if(sz[lson]<k) k-=sz[lson]+cnt[x],x=rson; 82 else x=lson; 83 } 84 } 85 int Find(int v,int w) 86 { 87 Rank(v,root); 88 if((t[root]>v&&!w)||(t[root]<v&&w)) return root;//! 89 int x=son[root][w^1]; 90 while(son[x][w]) x=son[x][w]; 91 return x; 92 } 93 } 94 using namespace Splay; 95 96 int main() 97 { 98 int n=read(),opt; 99 while(n--) 100 switch(opt=read()) 101 { 102 case 1: Insert(read(),root); break; 103 case 2: Delete(read(),root); break; 104 case 3: Rank(read(),root),printf("%d ",sz[son[root][0]]+1); break; 105 case 4: printf("%d ",t[Get_Rank(read(),root)]); break; 106 case 5: printf("%d ",t[Find(read(),1)]); break; 107 case 6: printf("%d ",t[Find(read(),0)]); break; 108 } 109 return 0; 110 }
LCT✔
模板:http://www.cnblogs.com/SovietPower/p/8615938.html
1 #include <cstdio> 2 #include <cctype> 3 #include <algorithm> 4 #define gc() getchar() 5 const int N=3e5+5; 6 7 inline int read() 8 { 9 int now=0;register char c=gc(); 10 for(;!isdigit(c);c=gc()); 11 for(;isdigit(c);now=now*10+c-'0',c=gc()); 12 return now; 13 } 14 namespace LCT 15 { 16 #define lson son[x][0] 17 #define rson son[x][1] 18 19 int fa[N],son[N][2],sum[N],val[N],sk[N]; 20 bool rev[N]; 21 inline void Update(int x){ 22 sum[x]=sum[lson]^sum[rson]^val[x]; 23 } 24 inline bool n_root(int x){ 25 return son[fa[x]][0]==x||son[fa[x]][1]==x; 26 } 27 inline void Rev(int x){ 28 std::swap(lson,rson), rev[x]^=1; 29 } 30 inline void PushDown(int x){ 31 if(rev[x]) Rev(lson),Rev(rson),rev[x]=0; 32 } 33 void Rotate(int x) 34 { 35 int a=fa[x],b=fa[a],l=son[a][1]==x,r=l^1; 36 if(n_root(a)) son[b][son[b][1]==a]=x; 37 if(son[x][r]) fa[son[x][r]]=a; 38 fa[a]=x, fa[x]=b, son[a][l]=son[x][r], son[x][r]=a; 39 Update(a); 40 } 41 void Splay(int x) 42 { 43 int t=1,a=x; sk[1]=x; 44 while(n_root(a)) sk[++t]=a=fa[a]; 45 while(t) PushDown(sk[t--]); 46 while(n_root(x)) 47 { 48 if(n_root(a=fa[x])) Rotate(son[a][1]==x^son[fa[a]][1]==a?x:a); 49 Rotate(x); 50 } 51 Update(x); 52 } 53 void Access(int x){ 54 for(int pre=0; x; x=fa[pre=x]) 55 Splay(x), rson=pre, Update(x); 56 } 57 void Make_root(int x){ 58 Access(x), Splay(x), Rev(x); 59 } 60 void Split(int x,int y){ 61 Make_root(x), Access(y), Splay(y); 62 } 63 int Find_root(int x) 64 { 65 Access(x), Splay(x); 66 while(lson) x=lson; 67 return x; 68 } 69 void Link(int x,int y) 70 { 71 Make_root(x); 72 if(Find_root(y)!=x) fa[x]=y; 73 } 74 void Cut(int x,int y) 75 { 76 Make_root(x); 77 if(Find_root(y)==x&&fa[x]==y&&!rson) 78 fa[x]=son[y][0]=0, Update(y); 79 } 80 } 81 using namespace LCT; 82 83 int main() 84 { 85 int n=read(),m=read(),opt,x,y; 86 for(int i=1; i<=n; ++i) val[i]=read(); 87 while(m--) 88 switch(opt=read(),x=read(),y=read(),opt) 89 { 90 case 0: Split(x,y),printf("%d ",sum[y]); break; 91 case 1: Link(x,y); break; 92 case 2: Cut(x,y); break; 93 case 3: Splay(x), val[x]=y; break; 94 } 95 return 0; 96 }
可是很多东西都不熟啊QAQ:http://www.cnblogs.com/SovietPower/category/1182810.html
fhq Treap✔
http://www.cnblogs.com/SovietPower/p/8431909.html
1 #include <cstdio> 2 #include <cctype> 3 #include <algorithm> 4 #define gc() getchar() 5 const int N=1e5+5; 6 7 inline int read() 8 { 9 int now=0,f=1;register char c=gc(); 10 for(;!isdigit(c);c=gc()) if(c=='-') f=-1; 11 for(;isdigit(c);now=now*10+c-'0',c=gc()); 12 return now*f; 13 } 14 namespace fhq_Treap 15 { 16 #define lson son[rt][0] 17 #define rson son[rt][1] 18 19 int tot,fa[N],son[N][2],sz[N],val[N],fix[N]; 20 inline int New_Node(int v){ 21 fix[++tot]=rand(), val[tot]=v, sz[tot]=1; 22 return tot; 23 } 24 inline void Update(int rt){ 25 sz[rt]=sz[lson]+sz[rson]+1; 26 } 27 void Split(int rt,int v,int &x,int &y) 28 { 29 if(!rt) x=y=0; 30 else{ 31 if(val[rt]<=v) x=rt,Split(rson,v,rson,y);//val[rt] not val[x].. 32 else y=rt,Split(lson,v,x,lson); 33 Update(rt); 34 } 35 } 36 int Merge(int x,int y) 37 { 38 if(!x||!y) return x^y; 39 if(fix[x]<fix[y]){ 40 son[x][1]=Merge(son[x][1],y), Update(x); 41 return x; 42 } 43 else{ 44 son[y][0]=Merge(x,son[y][0]), Update(y); 45 return y; 46 } 47 } 48 int Rank(int k,int rt) 49 { 50 while(1) 51 { 52 if(sz[lson]+1==k) return rt; 53 if(sz[lson]<k) k-=sz[lson]+1,rt=rson; 54 else rt=lson; 55 } 56 } 57 int Find(int rt,int w) 58 { 59 while(son[rt][w]) rt=son[rt][w]; 60 return rt; 61 } 62 } 63 using namespace fhq_Treap; 64 65 int main() 66 { 67 int n=read(),opt,v,x,y,z,root=0; 68 while(n--) 69 switch(opt=read(),v=read(),opt) 70 { 71 case 1: Split(root,v,x,y),x=Merge(x,New_Node(v)),root=Merge(x,y); 72 break; 73 case 2: Split(root,v,x,z),Split(x,v-1,x,y),y=Merge(son[y][0],son[y][1]),root=Merge(Merge(x,y),z); 74 break; 75 case 3: Split(root,v-1,x,y),printf("%d ",sz[x]+1),root=Merge(x,y); 76 break; 77 case 4: printf("%d ",val[Rank(v,root)]); 78 break; 79 case 5: Split(root,v-1,x,y),printf("%d ",val[Find(x,1)]),root=Merge(x,y); 80 break; 81 case 6: Split(root,v,x,y),printf("%d ",val[Find(y,0)]),root=Merge(x,y); 82 break; 83 } 84 return 0; 85 }
树链剖分
树套树 二维线段树
主席树 树上第k大(小)✔
区间第k大略
http://www.cnblogs.com/SovietPower/p/8443615.html
1 //10^5还是需要18*10^5的空间! 2 #include <cstdio> 3 #include <cctype> 4 #include <algorithm> 5 #define gc() getchar() 6 const int N=1e5+5; 7 8 int n,Q,cnt,ref[N],A[N],H[N],Enum,nxt[N<<1],to[N<<1],root[N],top[N],dep[N],sz[N],son[N],fa[N]; 9 10 inline int read() 11 { 12 int now=0,f=1;register char c=gc(); 13 for(;!isdigit(c);c=gc()) if(c=='-') f=-1; 14 for(;isdigit(c);now=now*10+c-'0',c=gc()); 15 return now*f; 16 } 17 inline void AddEdge(int u,int v) 18 { 19 to[++Enum]=v, nxt[Enum]=H[u], H[u]=Enum; 20 to[++Enum]=u, nxt[Enum]=H[v], H[v]=Enum; 21 } 22 namespace T//Seg_Tree 23 { 24 #define lson son[x][0] 25 #define rson son[x][1] 26 27 int tot,sum[N*17],son[N*17][2]; 28 void Insert(int x,int &y,int l,int r,int p) 29 { 30 sum[y=++tot]=sum[x]+1; 31 if(l<r){ 32 int m=l+r>>1; 33 if(p<=m) son[y][1]=rson,Insert(lson,son[y][0],l,m,p); 34 else son[y][0]=lson,Insert(rson,son[y][1],m+1,r,p); 35 } 36 } 37 int Query(int x,int y,int lca,int falca,int l,int r,int k) 38 { 39 if(l==r) return l; 40 int delta=sum[lson]+sum[son[y][0]]-sum[son[lca][0]]-sum[son[falca][0]]; 41 if(delta<k) return Query(rson,son[y][1],son[lca][1],son[falca][1],(l+r>>1)+1,r,k-delta); 42 return Query(lson,son[y][0],son[lca][0],son[falca][0],l,l+r>>1,k); 43 } 44 } 45 46 int Find(int x) 47 { 48 int l=1,r=cnt,mid; 49 while(l<r) 50 if(ref[mid=l+r>>1]<x) l=mid+1; 51 else r=mid; 52 return l; 53 } 54 void DFS1(int x) 55 { 56 int mx=0; sz[x]=1; 57 T::Insert(root[fa[x]],root[x],1,cnt,A[x]); 58 for(int v,i=H[x]; i; i=nxt[i]) 59 if((v=to[i])!=fa[x]) 60 { 61 fa[v]=x, dep[v]=dep[x]+1, DFS1(v), sz[x]+=sz[v]; 62 if(sz[v]>mx) mx=sz[v],son[x]=v; 63 } 64 } 65 void DFS2(int x,int tp) 66 { 67 top[x]=tp; 68 if(son[x]){ 69 DFS2(son[x],tp); 70 for(int i=H[x]; i; i=nxt[i]) 71 if(to[i]!=fa[x] && to[i]!=son[x]) DFS2(to[i],to[i]); 72 } 73 } 74 int LCA(int u,int v) 75 { 76 while(top[u]!=top[v]) 77 { 78 if(dep[top[u]]<dep[top[v]]) std::swap(u,v); 79 u=fa[top[u]]; 80 } 81 return dep[u]>dep[v]?v:u; 82 } 83 84 int main() 85 { 86 n=read(),Q=read(); 87 for(int i=1; i<=n; ++i) ref[i]=A[i]=read(); 88 for(int u,v,i=1; i<n; ++i) u=read(),v=read(),AddEdge(u,v); 89 std::sort(ref+1,ref+1+n), cnt=1; 90 for(int i=2; i<=n; ++i) if(ref[i]!=ref[i-1]) ref[++cnt]=ref[i]; 91 for(int i=1; i<=n; ++i) A[i]=Find(A[i]); 92 DFS1(1), DFS2(1,1); 93 int res=0,u,v,w,k; 94 while(Q--) 95 u=read()^res,v=read(),k=read(),w=LCA(u,v), 96 printf("%d ",res=ref[T::Query(root[u],root[v],root[w],root[fa[w]],1,cnt,k)]); 97 98 return 0; 99 }
可并堆 左偏树✔
http://www.cnblogs.com/SovietPower/p/8435041.html
1 #include <cstdio> 2 #include <cctype> 3 #include <algorithm> 4 //#define gc() getchar() 5 #define gc() (SS==TT&&(TT=(SS=IN)+fread(IN,1,MAXIN,stdin),SS==TT)?EOF:*SS++) 6 #define MAXIN 50000//这个到底需要多大啊QAQ 7 const int N=1e5+5,DEL=-1<<30; 8 9 char IN[MAXIN],*SS=IN,*TT=IN; 10 namespace Leftist_Tree 11 { 12 #define lson son[x][0] 13 #define rson son[x][1] 14 15 int fa[N],son[N][2],dis[N],val[N]; 16 int Merge(int x,int y) 17 { 18 if(!x||!y) return x^y; 19 if(val[x]>val[y]||(val[x]==val[y]&&x>y)) std::swap(x,y); 20 rson=Merge(rson,y), fa[rson]=x; 21 if(dis[lson]<dis[rson]) std::swap(lson,rson); 22 dis[x]=dis[rson]+1; 23 return x; 24 } 25 inline int Top(int x){ 26 while(fa[x]) x=fa[x]; 27 return x; 28 } 29 } 30 using namespace Leftist_Tree; 31 32 inline int read() 33 { 34 int now=0,f=1;register char c=gc(); 35 for(;!isdigit(c);c=gc()) if(c=='-') f=-1; 36 for(;isdigit(c);now=now*10+c-'0',c=gc()); 37 return now*f; 38 } 39 40 int main() 41 { 42 dis[0]=-1; 43 int n=read(),Q=read(),opt,x,y; 44 for(int i=1; i<=n; ++i) val[i]=read(); 45 while(Q--) 46 { 47 opt=read(),x=read(); 48 if(opt==1) 49 { 50 y=read(); 51 if(val[x]==DEL||val[y]==DEL||x==y) continue; 52 if((x=Top(x))!=(y=Top(y))) Merge(x,y); 53 } 54 else if(val[x]==DEL) puts("-1"); 55 else 56 { 57 printf("%d ",val[x=Top(x)]),val[x]=DEL; 58 fa[lson]=fa[rson]=0, Merge(lson,rson);//记得清空fa[]! 59 } 60 } 61 return 0; 62 }
数学,数论
CRT
扩展CRT
Lucas
扩展Lucas
线性求逆元✔
这么水的东西https://www.luogu.org/problemnew/show/P3811
1 #include <cstdio> 2 const int N=3e6+6; 3 4 int n,p,inv[N]; 5 6 int main() 7 { 8 scanf("%d%d",&n,&p); 9 inv[1]=1, puts("1"); 10 for(int i=2; i<=n; ++i) 11 printf("%d ",inv[i]=1ll*(p-p/i)*inv[p%i]%p); 12 13 return 0; 14 }
Miller Rabin
Pollard Rho
上面这俩。。
Catalan数
博弈论复习
高斯消元
莫比乌斯反演✔
做了。
图论
2-SAT
Matrix Tree✔
http://www.cnblogs.com/SovietPower/p/8463968.html
就是那样,只会写模板,不再写了。。
二分图匹配 匈牙利
欧拉路
哈密顿路
次小生成树
这个不写了。。倍增十分麻烦,到时候写LCT水过去吧。。
堆优化Dijkstra✔
我。。还是再写遍这个吧
https://www.luogu.org/problemnew/show/P3371
1 //memset(0x7f)后的值并不是0x7fffffff(略小)!woc才知道。 2 #include <queue> 3 #include <cstdio> 4 #include <cctype> 5 #include <cstring> 6 #include <algorithm> 7 #define gc() getchar() 8 #define pr std::pair<int,int> 9 #define mp std::make_pair 10 const int N=1e4+5,M=5e5+5,INF=0x3f3f3f3f; 11 12 int n,m,S,Enum,H[N],nxt[M],to[M],val[M],dis[N]; 13 std::priority_queue<pr> q; 14 bool vis[N]; 15 16 inline int read() 17 { 18 int now=0;register char c=gc(); 19 for(;!isdigit(c);c=gc()); 20 for(;isdigit(c);now=now*10+c-'0',c=gc()); 21 return now; 22 } 23 inline void AddEdge(int u,int v,int w){ 24 to[++Enum]=v, nxt[Enum]=H[u], H[u]=Enum, val[Enum]=w; 25 } 26 void Dijkstra() 27 { 28 memset(dis,0x3f,sizeof dis); 29 dis[S]=0, q.push(mp(0,S)); 30 while(!q.empty()) 31 { 32 int x=q.top().second;q.pop(); 33 if(vis[x]) continue; 34 vis[x]=1; 35 for(int v,i=H[x]; i; i=nxt[i]) 36 if(dis[v=to[i]]>dis[x]+val[i]) 37 { 38 dis[v]=dis[x]+val[i]; 39 if(!vis[v]) q.push(mp(-dis[v],v)); 40 } 41 } 42 } 43 44 int main() 45 { 46 n=read(),m=read(),S=read(); 47 for(int u,v,i=1; i<=m; ++i) u=read(),v=read(),AddEdge(u,v,read()); 48 Dijkstra(); 49 for(int i=1; i<=n; ++i) printf("%d ",dis[i]==INF?0x7fffffff:dis[i]); 50 return 0; 51 }
网络流
Dinic、ISAP、SPFA费用流略。
无源汇上下界网络流
有源汇上下界网络流
有源汇上下界最小流
字符串
KMP✔
https://www.luogu.org/problemnew/show/P3375
1 #include <cstdio> 2 #include <cstring> 3 const int N=1e6+5; 4 5 int len,fail[N]; 6 char p[N],s[N]; 7 8 void Get_fail() 9 { 10 fail[0]=fail[1]=0; 11 for(int i=1,j; i<len; ++i) 12 { 13 j=fail[i]; 14 while(s[i]!=s[j]&&j) j=fail[j]; 15 fail[i+1]=s[i]==s[j]?j+1:0; 16 } 17 } 18 void KMP() 19 { 20 for(int i=0,j=0,l=strlen(p); i<l; ++i) 21 { 22 while(p[i]!=s[j]&&j) j=fail[j]; 23 if(p[i]==s[j]) ++j; 24 if(j==len) printf("%d ",i-j+2); 25 } 26 for(int i=1; i<=len; ++i) printf("%d ",fail[i]); 27 } 28 29 int main() 30 { 31 scanf("%s%s",p,s), len=strlen(s), Get_fail(), KMP(); 32 return 0; 33 }
Manacher✔
http://www.cnblogs.com/SovietPower/p/8677979.html
1 /* 2 记录当前ex[]最大的回文中心id和最远延伸范围mx! 3 关于串的构造: 4 应该是 @ #A#B#C#B#A# $,而不是 @ A#B#C#B#A $ 5 比如 @a#b#b#c$,答案应是max{ex[i]}-1,而第二种很多情况下答案是max{ex[i]}. 6 最优解不改串分奇偶讨论感觉sxbk。。 7 */ 8 #include <cstdio> 9 #include <cstring> 10 #include <algorithm> 11 const int N=22000010; 12 13 int n,ex[N]; 14 char tmp[N>>1],s[N]; 15 16 void Init() 17 { 18 n=strlen(tmp), s[0]='@'; 19 for(int i=0; i<n; ++i) 20 s[i<<1|1]='#', s[(i<<1)+2]=tmp[i]; 21 s[n=2*n+2]='$', s[n-1]='#'; 22 } 23 void Manacher() 24 { 25 int res=0,mx=0,id; 26 for(int i=1; i<n; ++i) 27 { 28 if(i<mx) ex[i]=std::min(ex[id*2-i],mx-i); 29 else ex[i]=1; 30 while(s[i+ex[i]]==s[i-ex[i]]) ++ex[i]; 31 // if(ex[i]>res) res=ex[i];//不在这更新也对,懒得想了。。 32 if(i+ex[i]>mx) id=i,mx=i+ex[i],res=std::max(res,ex[i]); 33 } 34 printf("%d",res-1); 35 } 36 37 int main() 38 { 39 scanf("%s",tmp), Init(), Manacher(); 40 return 0; 41 }
后缀数组✔
http://www.cnblogs.com/SovietPower/p/8567563.html
1 #include <cstdio> 2 #include <cstring> 3 #include <algorithm> 4 const int N=1e6+5; 5 6 int n,tm[N],sa[N],rk[N],sa2[N],ht[N]; 7 char s[N]; 8 9 void Get_SA() 10 { 11 int *x=rk,*y=sa2,m=28; 12 for(int i=0; i<=m; ++i) tm[i]=0; 13 for(int i=1; i<=n; ++i) ++tm[x[i]=s[i]-'a'+1]; 14 for(int i=1; i<=m; ++i) tm[i]+=tm[i-1]; 15 for(int i=n; i; --i) sa[tm[x[i]]--]=i; 16 for(int k=1,p=0; k<n; k<<=1,m=p,p=0) 17 { 18 for(int i=n-k+1; i<=n; ++i) y[++p]=i; 19 for(int i=1; i<=n; ++i) if(sa[i]>k) y[++p]=sa[i]-k; 20 21 for(int i=0; i<=m; ++i) tm[i]=0; 22 for(int i=1; i<=n; ++i) ++tm[x[i]]; 23 for(int i=1; i<=m; ++i) tm[i]+=tm[i-1]; 24 for(int i=n; i; --i) sa[tm[x[y[i]]]--]=y[i]; 25 26 std::swap(x,y), p=x[sa[1]]=1; 27 for(int i=2; i<=n; ++i) 28 x[sa[i]]=y[sa[i]]==y[sa[i-1]]&&y[sa[i]+k]==y[sa[i-1]+k]?p:++p; 29 if(p>=n) break; 30 } 31 for(int i=1; i<=n; ++i) rk[sa[i]]=i; 32 ht[1]=0; 33 for(int k=0,p,i=1; i<=n; ++i) 34 { 35 if(rk[i]==1) continue; 36 if(k) --k; 37 p=sa[rk[i]-1];//ht[i]>=ht[i-1]-1 38 while(i+k<=n&&p+k<=n&&s[i+k]==s[p+k]) ++k; 39 ht[rk[i]]=k; 40 } 41 } 42 43 int main() 44 { 45 scanf("%s",s+1), n=strlen(s+1), Get_SA(); 46 for(int i=1; i<=n; ++i) printf("%d ",sa[i]);putchar(' '); 47 for(int i=2; i<=n; ++i) printf("%d ",ht[i]); 48 49 return 0; 50 }
AC自动机✔
http://www.cnblogs.com/SovietPower/p/8530327.html
1 #include <cstdio> 2 #include <cstring> 3 #include <algorithm> 4 const int N=1e6+5; 5 6 char s[N]; 7 struct AC_Automaton 8 { 9 int tot,fail[N],son[N][26],las[N],val[N],q[N]; 10 void Insert(char *s) 11 { 12 int l=strlen(s),x=0; 13 for(int id,i=0; i<l; ++i) 14 { 15 id=s[i]-'a'; 16 if(!son[x][id]) son[x][id]=++tot; 17 x=son[x][id]; 18 } 19 ++val[x]; 20 } 21 void Build() 22 { 23 int h=0,t=0; 24 for(int i=0; i<26; ++i) 25 if(son[0][i]) fail[son[0][i]]=0,q[t++]=son[0][i]; 26 while(h<t) 27 { 28 int x=q[h++]; 29 for(int v,i=0; i<26; ++i) 30 if(son[x][i]) 31 fail[v=son[x][i]]=son[fail[x]][i],q[t++]=v,las[v]=val[fail[v]]?fail[v]:las[fail[v]]; 32 else son[x][i]=son[fail[x]][i];//直接设son[]。 33 } 34 } 35 void Query(char *s) 36 { 37 int l=strlen(s),res=0,x=0; 38 for(int i=0; i<l; ++i) 39 { 40 x=son[x][s[i]-'a'];//先走一步 41 for(int j=x; j&&~val[j]; j=las[j]) 42 res+=val[j], val[j]=-1;//不能重复走。 43 } 44 printf("%d",res); 45 } 46 }ac; 47 48 int main() 49 { 50 int n; scanf("%d",&n); 51 while(n--) scanf("%s",s),ac.Insert(s); 52 ac.Build(), scanf("%s",s), ac.Query(s); 53 54 return 0; 55 }
1 #include <cstdio> 2 #include <cctype> 3 #include <cstring> 4 #include <algorithm> 5 #define gc() getchar() 6 const int N=152*72,S=26; 7 8 int n; 9 char s[152][72],p[1000005]; 10 11 struct AC_Automaton 12 { 13 int tot,son[N][27],fail[N],val[N],las[N],q[N],tm[152]; 14 void Init(){ 15 tot=0, memset(son,0,sizeof son), memset(val,0,sizeof val); 16 } 17 void Insert(char *s,int pos) 18 { 19 int l=strlen(s),x=0; 20 for(int id,i=0; i<l; ++i) 21 { 22 id=s[i]-'a'; 23 if(!son[x][id]) son[x][id]=++tot; 24 x=son[x][id]; 25 } 26 val[x]=pos; 27 } 28 void Build() 29 { 30 int h=0,t=0; 31 for(int i=0; i<S; ++i) 32 if(son[0][i]) fail[son[0][i]]=0,q[t++]=son[0][i]; 33 while(h<t) 34 { 35 int x=q[h++]; 36 for(int v,i=0; i<S; ++i) 37 if(son[x][i]) 38 fail[v=son[x][i]]=son[fail[x]][i],q[t++]=v,las[v]=val[fail[v]]?fail[v]:las[fail[v]]; 39 else son[x][i]=son[fail[x]][i]; 40 } 41 } 42 void Query(char *p) 43 { 44 int l=strlen(p),res=0,x=0; 45 memset(tm,0,sizeof tm); 46 for(int i=0; i<l; ++i) 47 { 48 x=son[x][p[i]-'a']; 49 for(int j=x; j; j=las[j]) ++tm[val[j]]; 50 } 51 for(int i=1; i<=n; ++i) if(res<tm[i]) res=tm[i]; 52 printf("%d ",res); 53 for(int i=1; i<=n; ++i) if(tm[i]==res) printf("%s ",s[i]); 54 } 55 }ac; 56 57 int main() 58 { 59 while(scanf("%d",&n),n){ 60 ac.Init(); 61 for(int i=1; i<=n; ++i) scanf("%s",s[i]),ac.Insert(s[i],i); 62 ac.Build(), scanf("%s",p), ac.Query(p); 63 } 64 return 0; 65 }
其它
Hash
判字符串相等
粘个代码 POJ.2758.Checking the Text(Hash 二分答案)
1 /* 2 题意:给定一个字符串,有两种操作:在字符串中插入一个字符、询问某两个位置开始的LCP的长度 3 4 处理出Hash,LCP可以通过 二分+Hash 解决 5 由于修改次数很小,只有200,直接暴力修改重构 Hash 6 7 长度起名叫len,不要再用l了。。 8 */ 9 #include<cstdio> 10 #include<cstring> 11 #include<algorithm> 12 #define ULL unsigned long long 13 using namespace std; 14 const int N=51000,base=131; 15 16 int n,len,pos[N]; 17 char s[N]; 18 ULL pw[N],hs[N]; 19 20 void Init(int fr) 21 { 22 for(int i=fr;i<=len;++i) 23 hs[i]=hs[i-1]*base+s[i]; 24 } 25 ULL Get_Hash(int l,int r) 26 { 27 return hs[r]-hs[l-1]*pw[r-l+1]; 28 } 29 int Solve(int x,int y) 30 { 31 int l=0,r=len-max(x,y)+1,m; 32 while(l<=r) 33 { 34 m=l+r>>1; 35 if(Get_Hash(x,x+m-1)==Get_Hash(y,y+m-1)) l=m+1; 36 else r=m-1; 37 } 38 return r; 39 } 40 41 int main() 42 { 43 // freopen("2758.in","r",stdin); 44 45 pw[0]=1; 46 for(int i=1;i<N;++i) 47 pw[i]=pw[i-1]*base; 48 49 scanf("%s",s+1); 50 n=len=strlen(s+1); 51 Init(1); 52 for(int i=1;i<=n;++i) 53 pos[i]=i; 54 int t,a,b;char opt[5]; 55 scanf("%d",&t); 56 while(t--) 57 { 58 scanf("%s",opt); 59 if(opt[0]=='Q') 60 { 61 scanf("%d%d",&a,&b); 62 printf("%d ",Solve(pos[a],pos[b])); 63 } 64 else 65 { 66 scanf("%s%d",opt,&a); 67 ++len; 68 if(a>len) a=len; 69 memcpy(s+a+1,s+a,(len-a)*sizeof(char)); 70 s[a]=opt[0]; 71 for(int i=n;pos[i]>=a;--i)//每一位后移,暴力处理 72 ++pos[i]; 73 Init(a); 74 } 75 } 76 return 0; 77 }