模板大全
目录
最小生成树
#include<cstdio> #include<algorithm> #define ct register int #define fr(i,a,b) for(int i=a;i<=b;i++) using namespace std; int read(){int x=0,f=1;char c=getchar(); for(;c<'0'||c>'9';c=getchar())if(c=='-')f=-1; for(;'0'<=c&&c<='9';c=getchar())x=(x<<3)+(x<<1)+(c^48);return x*f;} struct edge{int from,to,dis; bool operator <(const edge& rhs)const{return dis<rhs.dis;} }; edge edges[200005];int father[200005],m,n; int find(int x){if(father[x]==x)return x;father[x]=find(father[x]);return father[x];} void init(){fr(i,1,m)father[i]=i;} void merge(int x,int y){father[find(x)]=find(y);} int main(){n=read();m=read(); for(int i=1;i<=m;i++){int a=read(),b=read(),c=read(); edges[i].from=a;edges[i].to=b;edges[i].dis=c;} sort(edges+1,edges+m+1);init(); ct ans=0,tn=0,k=1; while(tn<n-1){ if(find(edges[k].to)!=find(edges[k].from)) merge(edges[k].to,edges[k].from),ans+=edges[k].dis,tn++; k++;}printf("%d",ans); }
并查集
#include<cstdio> using namespace std; int n,m,z,x,y,fa[100010]; int getfa(int x){return x==fa[x]?x:fa[x]=getfa(fa[x]);} //if x has no father,just means its father is itself ,just return it //or ,just means it has father ,just look for it's ancestor and return the wanted num int main(){scanf("%d%d",&n,&m);//read the total_num of numbers and the total_num of operations for(int i=1;i<=n;i++)fa[i]=i;//initialization:set every element's father as themselves(no father case) for(int i=1;i<=m;i++){scanf("%d%d%d",&z,&x,&y);//read the operation_num ,x, and y //if z==1,just merge set_x and set_y,if z==2,just make a judge if x and y are in the same set z==1?fa[getfa(x)]=getfa(y):getfa(x)==getfa(y)?puts("Y"):puts("N");}return 0; //operation 1:set set_x's ancestor's father as set_y's ancestor(just means merge them together //operation 2:make a judge if set_x amd set_y have the same ancestor,if have,just out"Y",or out"N" }//Union-Find_set's template ,marked by yodel
最大流
#include<cstdio> #include<cstring> #include<queue> #define MAXN 10010 #define MAXM 200010 #define INF 1073741823 //------------------optimization-------------------------------- #define getchar() (S==T&&(T=(S=BB)+fread(BB,1,1<<15,stdin),S==T)?EOF:*S++) char BB[1<<15],*S=BB,*T=BB; int read(){int x=0,f=1;char ch=getchar(); for(;ch<'0'||ch>'9';ch=getchar())if(ch=='-')f=-1; for(;'0'<=ch&&ch<='9';ch=getchar())x=(x<<3)+(x<<1)+(ch^48);return x*f;} void outint(int x){if(x>=10) outint(x/10);putchar(x%10+'0');} //------------------optimization above--------------------------------------- using namespace std; int n,m,A,B,C,sz=1,s,t; int to[MAXM],v[MAXM],pre[MAXM],las[MAXN],H[MAXN],cur[MAXN],gap[MAXN]; queue<int>Q; void ins(int a,int b,int c){ sz++;to[sz]=b;v[sz]=c;pre[sz]=las[a];las[a]=sz; sz++;to[sz]=a;v[sz]=0;pre[sz]=las[b];las[b]=sz;} //insert edge void bfs(){Q.push(t);memset(H,-1,sizeof(H));memset(gap,0,sizeof(gap));//initialization H[t]=0;gap[0]=1;//gap optimization while(!Q.empty()){int tmp=Q.front();Q.pop(); for(int i=las[tmp];i;i=pre[i])if(H[to[i]]==-1)H[to[i]]=H[tmp]+1,gap[H[to[i]]]++,Q.push(to[i]);}} int dfs(int x,int F){if(x==t)return F;int used=0,w; for(int i=cur[x];i;i=pre[i]) if(v[i]>0&&H[to[i]]+1==H[x]){w=min(v[i],F-used),w=dfs(to[i],w); v[i]-=w,v[i^1]+=w,used+=w; if(v[i]>0)cur[x]=i;if(F==used)return F; }gap[H[x]]--;if(!gap[H[x]])H[s]=n+2; gap[++H[x]]++;cur[x]=las[x];return used;} int SAP(){int ans=0;for (int i=1;i<=n;i++)cur[i]=las[i];while(H[s]<n+2)ans+=dfs(s,INF);return ans;} int main(){n=read(),m=read(),s=read(),t=read(); for(int i=1;i<=m;i++)A=read(),B=read(),C=read(),ins(A,B,C); bfs();outint(SAP());return 0;}
费用流
#include<cstdio> #include<algorithm> using std::min; #define getchar() (W==C&&(C=(W=BB)+fread(BB,1,1<<15,stdin),W==C)?EOF:*W++) char BB[1<<15],*W=BB,*C=BB; int read(){int x=0,f=1;char ch=getchar(); for(;ch<'0'||ch>'9';ch=getchar())if(ch=='-')f=-1; for(;'0'<=ch&&ch<='9';ch=getchar())x=(x<<3)+(x<<1)+(ch^48);return x*f;} void outint(int x){if(x>=10) outint(x/10);putchar(x%10+'0');} #define oo 1000000000 #define N 10100 #define M 200100 int n,m,S,T,i,x,y,f,c,t[N]; struct edge{int to,next,f,cost;}l[M];int e; #define add(x,y,f,c) {l[++e]=(edge){y,t[x],f,c};t[x]=e;} int g[N],tot,h[N],_t[N],base,now,rt,head[N],next[N],*dy[N]; #define fu(x,y) {dy[y]=&x;x=y;} #define _fu(x,y) {dy[y]=x;*x=y;} void merge(int &x,int y){ if (g[x]<g[y]){fu(next[y],head[x]) fu(head[x],y) } else {fu(next[x],head[y]) fu(head[y],x) ;x=y;} } void merges(int &x){int y=next[x],r;while (y) r=next[y],merge(x,y),y=r; } bool spfa(){for (i=1;i<=n;++i)g[i]=oo;g[rt=T]=0; do{x=rt;merges(rt=head[rt]); dy[x]=0,next[x]=head[x]=0,base=g[x]; for(_t[x]=i=t[x];i;i=l[i].next) if(l[i^1].f&&g[y=l[i].to]>(now=base-l[i].cost+h[x]-h[y])) { if(now>g[S])continue;g[y]=now; if (y!=rt) { if (dy[y]!=0) _fu(dy[y],next[*dy[y]]) else if (!rt) {rt=y;continue;}merge(rt,y);} } }while (rt);if(g[S]==oo) return 0; for(x=1;x<=n;++x)h[x]+=g[x];return 1;} bool in[N]; int ansf=0,ansc=0; int dfs(int x,int f){if(x==T)return f; in[x]=1;int f0=f,del,y; for (int &i=_t[x];i;i=l[i].next) if (l[i].f&&(!in[y=l[i].to])&&(l[i].cost==h[x]-h[y])){ del=dfs(y,min(l[i].f,f)); l[i].f-=del;l[i^1].f+=del;f-=del; if (!f) {in[x]=0;return f0;} }in[x]=0;return f0-f;} int main(){n=read(),m=read(),S=read(),T=read();e=1; for (i=1;i<=m;++i) {x=read(),y=read(),f=read(),c=read(); add(x,y,f,c) add(y,x,0,-c)} while (spfa())f=dfs(S,oo),ansf+=f,ansc+=f*h[S];outint(ansf);putchar(' ');outint(ansc);} //308ms in total
树链剖分
#include<cstdio> #define ct register int #define f(a) for(ct i=1;i<=a;i++) char ss[1<<17],*A=ss,*B=ss; inline char gc(){if(A==B){B=(A=ss)+fread(ss,1,1<<17,stdin);if(A==B)return EOF;}return*A++;} int I(){int x=0,f=1;char ch=getchar(); for(;ch<'0'||ch>'9';ch=getchar())if(ch=='-')f=-1; for(;'0'<=ch&&ch<='9';ch=getchar())x=(x<<3)+(x<<1)+(ch^48);return x*f;} const int N=5e5+5; typedef int array[N]; typedef long long ll; struct edges{int nx,to;}e[N<<1]; int n,m,s,mod,tot,tmp;array a,b,depth,fa,son,size,top,id,real,fi;ll c1[N],c2[N]; void dfs1(ct u){depth[u]=depth[fa[u]]+(size[u]=1); for(ct i=fi[u],v;i;i=e[i].nx) if((v=e[i].to)!=fa[u]){fa[v]=u;dfs1(v);size[u]+=size[v]; if(size[v]>size[son[u]])son[u]=v;}} void dfs2(ct u){ son[fa[u]]==u?top[u]=top[fa[u]]:top[u]=u; real[id[u]=++tmp]=u;if(son[u])dfs2(son[u]); for(ct v,i=fi[u];i;i=e[i].nx) if((v=e[i].to)!=fa[u]&&v!=son[u])dfs2(v);} inline void insert(ct x,ll w){for(ct i=x;i<=n;i+=i&(-i))c1[i]+=w,c2[i]+=(ll)x*w;} inline ll sigma(ct x){ll sum=0;for(ct i=x;i;i-=i&(-i))sum+=(ll)(x+1)*c1[i]-c2[i];return sum;} inline void swap(ct&x,ct&y){x^=y,y^=x,x^=y;} void change(ct u,ct v,ct w){ while(top[u]!=top[v]){ if(depth[top[u]]<depth[top[v]])swap(u,v); insert(id[top[u]],w);insert(id[u]+1,-w); u=fa[top[u]];} if(depth[u]>depth[v])swap(u,v); insert(id[u],w);insert(id[v]+1,-w);} inline ll sum(ct u,ct v){ll sum=0; while(top[u]!=top[v]){ if(depth[top[u]]<depth[top[v]])swap(u,v); sum+=sigma(id[u])-sigma(id[top[u]]-1); u=fa[top[u]];} if(depth[u]>depth[v])swap(u,v); sum+=sigma(id[v])-sigma(id[u]-1); return sum%mod;} inline void add(ct u,ct v){e[++tot]=(edges){fi[u],v};fi[u]=tot;} int main(){n=I(),m=I(),s=I(),mod=I(); f(n)a[i]=I();ct u,v;f(n-1)u=I(),v=I(),add(u,v),add(v,u); dfs1(s);dfs2(s);f(n)b[i]=a[real[i]];f(n)insert(i,b[i]-b[i-1]); ct op,x,y,z; f(m){op=I();x=I(); if(op==1)y=I(),z=I(),change(x,y,z); else if(op==2)y=I(),printf("%d\n",sum(x,y)); else if(op==3)y=I(),insert(id[x],y),insert(id[x]+size[x]-1+1,-y); else printf("%d\n",(sigma(id[x]+size[x]-1)-sigma(id[x]-1))%mod);} return 0;}
左偏树
#include <cstdio> #define N 100010 using namespace std; #define cint register int #define getchar() (SS==TT&&(TT=(SS=BB)+fread(BB,1,1<<15,stdin),SS==TT)?EOF:*SS++) char BB[1<<15],*SS=BB,*TT=BB; int read(){cint x=0,f=1;char ch=getchar(); while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();} while('0'<=ch&&ch<='9'){x=(x<<3)+(x<<1)+(ch^48);ch=getchar();}return x*f;} void swap(int &x,int &y){cint t=x;x=y,y=t;} int ch[N][2],val[N],dis[N],f[N],n,m; int merge(int x,int y){if(x==0||y==0)return x+y; if(val[x]>val[y]||(val[x]==val[y]&&x>y))swap(x,y); ch[x][1]=merge(ch[x][1],y);f[ch[x][1]]=x; if(dis[ch[x][0]]<dis[ch[x][1]])swap(ch[x][0],ch[x][1]); dis[x]=dis[ch[x][1]]+1;return x;} int getf(int x){while(f[x]) x=f[x];return x;} void pop(int x){val[x]=-1;f[ch[x][0]]=f[ch[x][1]]=0;merge(ch[x][0],ch[x][1]);} main(){n=read(),m=read();dis[0]=-1; for(cint i=1;i<=n;i++)val[i]=read(); for(cint i=1;i<=m;i++){cint com=read(); if(com==1){cint x=read(),y=read(); if(val[x]==-1||val[y]==-1)continue; if(x==y)continue; int fx=getf(x),fy=getf(y);merge(fx,fy);} else{cint x=read(); if(val[x]==-1)puts("-1"); else{cint y=getf(x);printf("%d\n",val[y]);pop(y);}}}}
矩阵加速
#include<cstdio> const int N=3,P=1000000007; #define f(a,c) for(int a=0;a<c;a++) struct jz{int m[N][N]; jz(bool e=0){f(i,N){f(j,N)m[i][j]=0;m[i][i]=e;}}}; jz operator*(const jz &a,const jz &b){jz c;f(k,N)f(i,N)if(a.m[i][k])f(j,N) c.m[i][j]=(c.m[i][j]+1ll*a.m[i][k]*b.m[k][j])%P;return c;} jz operator*=(jz &a,const jz &b){return a=a*b;} jz fpw(jz a,int n){jz ans(1);for(;n;n>>=1,a*=a)if(n&1)ans*=a;return ans;} int main(){int T,n;scanf("%d",&T); while(T--){scanf("%d",&n);jz ans; ans.m[0][2]=ans.m[1][0]=ans.m[2][1]=ans.m[2][2]=1;ans=fpw(ans,n); printf("%d\n",ans.m[2][1]);}return 0;}
树状数组1(单点修改+区间和)
#include<cstdio> using namespace std; int a[500010],n,c[500010],m,i,t,T,x,y,r; int A(int p,int t){for(;p<=n;p+=p&-p)c[p]+=t;} int P(int p){for(r=0;p;p-=p&-p)r+=c[p];return r;} main(){scanf("%d%d",&n,&m); for(i=1;i<=n;i++)scanf("%d",&t),A(i,t); while(m--)scanf("%d%d%d",&T,&x,&y),T==1?A(x,y):printf("%d\n",P(y)-P(x-1)); }
FFT a*b
#include<cstdio> #include<cmath> #define re register int #define N 180000 typedef int arr[N]; struct cp{double x,y; inline cp operator+(const cp&b){return (cp){x+b.x,y+b.y};} inline cp operator-(const cp&b){return (cp){x-b.x,y-b.y};} inline cp operator*(const cp&b){return (cp){x*b.x-y*b.y,x*b.y+y*b.x};} }a[N],b[N],w[N]; int n,K=1;arr r,c;char s1[N>>1],s2[N>>1]; inline void swap(cp&a,cp&b){cp t=a;a=b;b=t;} const double pi=3.14159265358; void FFT(cp*const a,const re l,const re tp){ for(re i=0;i<l;++i)if(i>r[i])swap(a[i],a[r[i]]); for(re i=2;i<=l;i<<=1){ re d=i>>1;cp e=(cp){cos(pi/d),tp*sin(pi/d)}; for(re j=d;j>=0;j-=2)w[j]=w[j>>1]; for(re j=1;j<d;j+=2)w[j]=e*w[j-1]; for(re j=0;j<l;j+=i){cp*x=a+j,*y=x+d; for(re k=0;k<d;++k){cp o=y[k]*w[k];y[k]=x[k]-o;x[k]=x[k]+o;}}}} int main(){scanf("%d%s%s",&n,s1,s2);--n; while(K<=(n<<1)+1)K<<=1;w[0].x=1; for(re i=0;i<=n;++i)a[i].x=s1[n-i]^48; for(re i=0;i<=n;++i)b[i].x=s2[n-i]^48; for(re i=0,j=0;i<K;++i){r[i]=j;for(re l=K>>1;(j^=l)<l;l>>=1);} FFT(a,K,1);FFT(b,K,1); for(re i=0;i<K;++i)a[i]=a[i]*b[i]; FFT(a,K,-1);re len=(n<<1); for(re i=0;i<=(n<<1);++i)c[i]=int(a[i].x/K+0.1); for(re i=0;i<=(n<<1);++i)if(c[i]>10){ c[i+1]+=c[i]/10;c[i]%=10;if(i==len)++len; }while(!c[len]&&len)--len; for(re i=len;i>=0;--i)printf("%d",c[i]);return 0;}
单源最短路径
#include<cstdio> using namespace std; #define ct register int #define f(i,a,b) for(ct i=a;i<=b;i++) #define getchar() (SS==TT&&(TT=(SS=BB)+fread(BB,1,1<<15,stdin),SS==TT)?EOF:*SS++) char BB[1<<15],*SS=BB,*TT=BB; int I(){int x=0,f=1;char ch=getchar(); for(;ch<'0'||ch>'9';ch=getchar())if(ch=='-')f=-1; for(;'0'<=ch&&ch<='9';ch=getchar())x=(x<<3)+(x<<1)+(ch^48);return x*f;} void outint(int x){if(x>=10) outint(x/10);putchar(x%10+'0');} const int Max=2147483647; int u[500001],v[500001],w[500001],n,m,s; long long dis[10001]; int main(){n=I(),m=I(),s=I(); f(i,1,n)dis[i]=Max;dis[s]=0; f(i,1,m)u[i]=I(),v[i]=I(),w[i]=I(); f(i,1,n){bool ch=0; f(j,1,m)if(dis[v[j]]>dis[u[j]]+w[j])ch=1,dis[v[j]]=dis[u[j]]+w[j]; if(ch==0)break;} f(i,1,n)outint(dis[i]),putchar(' ');return 0;}
三分法
#include<stdio.h> int n;double a[13]; inline double f(const double x){double ret=0;for(int i=n;i;--i)ret=ret*x+a[i];return ret;} int main(){double left,right,mid; scanf("%d%lf%lf",&n,&left,&right); for(int i=n;i;--i)scanf("%lf",a+i),a[i]*=i; while(right-left>1e-6) f(mid=(right+left)/2)>0?left=mid:right=mid; printf("%.5lf\n",left); }
VEB树
典藏版
#include<iostream> #include<math.h> #define NIL 9999 #define MAX 100 using namespace std; struct VT{ int u,min,max;VT*summary=NULL;VT*cluster[MAX]; };//veb_tree's point void build(VT*V,int u){//build a veb_tree V->u=u;int min=NIL,max=NIL; for(int j=0;j<MAX;j++)V->cluster[j]=NULL; if(u!=2){int su=(int)sqrt((double)u); V->summary=new VT;build(V->summary,su); for(int i=0;i<su;i++)V->cluster[i]=new VT,build(V->cluster[i],su);}} void swap(int *a,int *b){int temp=*a;*a=*b;*b=temp;} int high(int x,int u){return (int)floor(x/sqrt((double)u));} int low(int x,int u){return x%(int)sqrt((double)u);} int index(int x,int y,int u){return x*(int)sqrt((double)u)+y;} int wmin(VT*V){return V->min;}//return the minest element inside tree int wmax(VT*V){return V->max;}//return the biggest element inside tree bool ifreal(VT*V,int x,int u){//make a judge if an element is inside the set if(x==V->min||x==V->max)return 1; else{if(V->u==2)return 0; else return ifreal(V->cluster[high(x,u)],low(x,u),u);}} int successor(VT*V,int x,int u){//search for successor if(V->u==2){if(x==0&&V->max==1)return 1;else return NIL;} else{if(V->min!=NIL&&x<V->min)return V->min; else{int max_low=wmax(V->cluster[high(x,u)]); if(max_low!=NIL && low(x,u)<max_low) { int offset=successor(V->cluster[high(x,u)],low(x,u),u); return index(high(x,u),offset,u);} else{int succ_cluster=successor(V->summary,high(x,u),u); if(succ_cluster==NIL)return NIL; else{int offset=wmin(V->cluster[succ_cluster]); return index(succ_cluster,offset,u);}}}}} int predecessor(VT*V,int x,int u){//search for predecessor if(V->u==2){if(x==1&&V->min==0)return 0;else return NIL;} else{if(V->max!=NIL && x>V->max)return V->max; else{int min_low=wmin(V->cluster[high(x,u)]); if(min_low!=NIL && low(x,u)>min_low){ int offset=predecessor(V->cluster[high(x,u)],low(x,u),u); return index(high(x,u),offset,u);} else{int pred_cluster=predecessor(V->summary,high(x,u),u); if(pred_cluster==NIL) { if(V->min!=NIL&&x>V->max)return V->min;else return NIL;} else{int offset=wmin(V->cluster[pred_cluster]); return index(pred_cluster,offset,u);}}}}} void IET(VT*V,int x){V->min=x;V->max=x;}//insert empty tree void IE(VT*V,int x,int u){//insert element if(V->min==NIL)IET(V,x); else{if(x<V->min)swap(&x,&V->min);//case one if(V->u>2){//case two if(wmin(V->cluster[high(x,u)])==NIL) IE(V->summary,high(x,u),u),IET(V->cluster[high(x,u)],low(x,u)); else IE(V->cluster[high(x,u)],low(x,u),u); }if(x>V->max)V->max=x;//case three }} void DE(VT*V,int x,int u){//delete element if(V->min==V->max)V->min=NIL,V->max=NIL; else{if(V->u==2)x==0?V->min=1:V->min=0,V->max=V->min; else if(x==V->min){int first_cluster=wmin(V->summary); x=index(first_cluster,wmin(V->cluster[first_cluster]),u); V->min=x;DE(V->cluster[high(x,u)],low(x,u),u); if(wmin(V->cluster[high(x,u)])==NIL){ DE(V->summary,high(x,u),u); if(x==V->max){int summary_max=wmax(V->summary); if(summary_max==NIL)V->max=V->min; else V->max=index(summary_max,wmax(V->cluster[summary_max]),u);}} else if(x==V->max)V->max=index(high(x,u),wmax(V->cluster[high(x,u)]),u);}}} void check(VT*V,int u){int x; int a[]={2,3,4,5,7,14,15};build(V,u); for(int i=0;i<7;i++){IE(V,a[i],u);} cout<<"请输入你要查询的数据:";cin>>x; if(ifreal(V,x,u))cout<<"该数据存在VEB树中"<<endl; else cout<<"该数据不存在VEB树中"<<endl; cout<<"请输入你要删除的数据:";cin>>x; cout<<"请输入你要查询的数据:";cin>>x; if(ifreal(V,x,u))cout<<"该数据存在VEB树中"<<endl; else cout<<"该数据不存在VEB树中"<<endl;} int main(){int u;cin>>u;VT*V=new VT;check(V,u);return 0;}
zkw版
#include <stdio.h> #define r register #define getchar() (S==TT&&(TT=(S=BB)+fread(BB,1,1<<15,stdin),TT==S)?EOF:*S++) char BB[1<<15],*S=BB,*TT=BB; inline int in(){ r int x=0;r char c;for(;(c=getchar())<'0'||c>'9';); for(x=c-'0';(c=getchar())>='0'&&c<='9';x=(x<<3)+(x<<1)+c-'0'); return x;}bool b[1<<20]; int t[1<<21|1],M,n,q; inline void A(int k,int v){for (k+=M; k; k>>=1)t[k]+=v;} inline int Get_Min(int k){for (;k<=M;k=t[k<<1]?k<<1:k<<1|1);return k-M-1;} inline int Get_Max(int k){for (;k<=M;k=t[k<<1|1]?k<<1|1:k<<1);return k-M-1;} inline int prefix(int v){for(v+=M;v!=1;v>>=1)if((v&1)&&t[v^1])return Get_Max(v^1);return -1;} inline int suffix(int v){for(v+=M;v!=1;v>>=1)if((~v&1)&&t[v^1])return Get_Min(v^1);return -1;} int main(){for(n=in(),q=in(),M=1;M<=n;M<<=1); while(q--){r int op=in(),x; if(op==1){if (!b[x=in()+1]) b[x]=1,A(x,1);}else if(op==2){if (b[x=in()+1]) b[x]=0,A(x,-1);}else if(op==3) printf("%d\n",t[1]?Get_Min(1):-1);else if(op==4) printf("%d\n",t[1]?Get_Max(1):-1);else if(op==5) printf("%d\n",prefix(in()+1));else if(op==6) printf("%d\n",suffix(in()+1));else printf("%d\n",(b[x=in()+1]?1:-1));}}
线段树(区间乘法,区间加法,区间和)
#include <cstdio> const int maxn=100001<<2|1; #define L long long L sum[maxn],mul[maxn],add[maxn],P; #define ls l,m,id<<1 #define rs m+1,r,id<<1|1 #define ARGS L k,L b #define NODE int l,int r,int id L I(){L x=0,f=1;char c=getchar(); for(;c<'0'||c>'9';c=getchar())if(c=='-')f=-1; for(;'0'<=c&&c<='9';c=getchar())x=(x<<3)+(x<<1)+(c^48);return x*f;} void update(int id){sum[id]=sum[id<<1]+sum[id<<1|1];} void color(NODE,ARGS){sum[id]=(sum[id]*k+(r-l+1)*b)%P; mul[id]=mul[id]*k%P;add[id]=(add[id]*k+b)%P;} void push(int l,int r,int id){ if(mul[id]!=1||add[id]!=0){int m=(l+r)>>1; color(ls,mul[id],add[id]);color(rs,mul[id],add[id]); update(id);mul[id]=1,add[id]=0;}} void build(NODE){if(l==r)sum[id]=I(); else{int m=(l+r)>>1;build(ls),build(rs),update(id);} mul[id]=1,add[id]=0;} void modify(NODE,int nl,int nr,ARGS){ if(nl<=l&&r<=nr)color(l,r,id,k,b); else{push(l,r,id); int m=(l+r)>>1;if(nl<=m)modify(ls,nl,nr,k,b); if(m<nr)modify(rs,nl,nr,k,b);update(id);}} L query(NODE,int nl,int nr){if(nl<=l&&r<=nr)return sum[id]; push(l,r,id);L res=0; int m=(l+r)>>1;if(nl<=m)res+=query(ls,nl,nr); if(m<nr)res+=query(rs,nl,nr);return res%P;} int main(){int n,m;n=I();m=I();P=I(); build(1,n,1);int c,x,y,k; for(int i=0;i<m;++i){ c=I();x=I();y=I();if(c!=3)k=I(); switch(c){case 1:modify(1,n,1,x,y,k,0);break; case 2:modify(1,n,1,x,y,1,k);break; case 3:printf("%lld\n",query(1,n,1,x,y));break; }}return 0;}
KMP
#include<cstdio> #include<cstring> int len1,len2,ne[1000001];char s2[1000001],s1[1000001]; void out(int x){if(x>=10)out(x/10);putchar(x%10+'0');} void sb(){ for(int i=2,j=0;i<=len2;i++){while(s2[i]!=s2[j+1]&&j>0)j=ne[j]; if(s2[i]==s2[j+1])ne[i]=++j;}} void kmp(){for(int i=1,j=0;i<=len1;i++){ while(s1[i]!=s2[j+1]&&j>0)j=ne[j]; if(s1[i]==s2[j+1])++j;if(j==len2)printf("%d\n",i-len2+1),j=ne[len2];}} using namespace std; int main(){scanf("%s%s",s1+1,s2+1); len1=strlen(s1+1),len2=strlen(s2+1);sb();kmp(); for(int i=1;i<=len2;i++)out(ne[i]),putchar(' '); }
线性筛素数
#include<cstdio> using namespace std; bool check[10000005];int prime[10000000],tot=0,w; int main(){int n,m;scanf("%d%d",&n,&m); for(int i=2;i<n;i++){if(!check[i])prime[tot++]=i; for(int j=0;j<tot;j++){ if(i*prime[j]>n)break;check[i*prime[j]]=1; if (i%prime[j]==0)break;}}check[1]=1; for(int i=1;i<=m;i++)scanf("%d",&w),!check[w]?printf("Yes\n"):printf("No\n"); }
负环
#include <cstdio> #define f(a,b,c) for(int a=b;a<=c;a++) #define M 200010 struct edge{int dst,len,next;}e[M<<1]; int t,n,m,N,via[M],dist[M];bool used[M]; inline void init(void){scanf("%d%d",&n,&m); f(i,0,n-1)via[i]=-1,dist[i]=0,used[i]=0;N=0; f(i,0,m-1){int x,y,l;scanf("%d%d%d",&x,&y,&l);x--;y--; e[N].dst=y;e[N].len=l;e[N].next=via[x];via[x]=N++; if(l>=0)e[N].dst=x,e[N].len=l,e[N].next=via[y],via[y]=N++;}} bool spfa(int now){used[now]=true; for(int i=via[now];i!= -1;i=e[i].next){ const int next=e[i].dst; if(dist[next]>dist[now]+e[i].len){ dist[next]=dist[now]+e[i].len; if(used[next])return 1;if(spfa(next))return 1;}} used[now]=0;return 0;} int main(void){scanf("%d",&t); f(j,0,t-1){init();bool flag=0; f(i,0,n-1)if(spfa(i)){flag=1;break;} std::puts(flag?"YE5":"N0");}return 0;}
Splay
#include<cstdio> #include<iostream> using namespace std; #define N 200005 const int MAXN=1e6+10;int n,m,root; struct node{int siz,fa,ch[2];bool rev;}T[N]; #define getchar() (W==C&&(C=(W=BB)+fread(BB,1,1<<15,stdin),W==C)?EOF:*W++) char BB[1<<15],*W=BB,*C=BB; int I(){int x=0,f=1;char ch=getchar(); for(;ch<'0'||ch>'9';ch=getchar())if(ch=='-')f=-1; for(;'0'<=ch&&ch<='9';ch=getchar())x=(x<<3)+(x<<1)+(ch^48);return x*f;} inline void pd(int rt){if(T[rt].rev)swap(T[rt].ch[1],T[rt].ch[0]), T[rt].rev=0,T[T[rt].ch[0]].rev^=1,T[T[rt].ch[1]].rev^=1;} inline void pu(int rt){T[rt].siz=T[T[rt].ch[0]].siz+T[T[rt].ch[1]].siz+1;return;} int find(int rt,int x) {if(rt==0)return 0;pd(rt); if(x<=T[T[rt].ch[0]].siz)return find(T[rt].ch[0],x); if(x==T[T[rt].ch[0]].siz+1)return rt; return find(T[rt].ch[1],x-T[T[rt].ch[0]].siz-1);} inline void rotate(int &rt,int x){ int y=T[x].fa,q=T[y].fa;bool dy=T[y].ch[1]==x,dz=T[q].ch[1]==y; pd(y);if(rt==y)rt=x,T[x].fa=q;else T[q].ch[dz]=x,T[x].fa=q; T[y].ch[dy]=T[x].ch[dy^1],T[T[x].ch[dy^1]].fa=y; T[x].ch[dy^1]=y,T[y].fa=x;pu(y);return;} void splay(int &rt,int x){pd(x); while(rt!=x){int y=T[x].fa,q=T[y].fa; if(y!=rt)if(T[y].ch[1]==x^T[q].ch[1]==y)rotate(rt,x);else rotate(rt,y); rotate(rt,x);}pu(x);return;} void out(int rt){if(rt==0)return;pd(rt);out(T[rt].ch[0]); if(rt>1&&rt<n+2)printf("%d ",rt-1);out(T[rt].ch[1]);} int main(){n=I(),m=I(); for(int i=1;i<=n+2;i++)T[i].siz=n+3-i,T[i].fa=i-1,T[i].ch[1]=i+1; T[n+2].ch[1]=0,root=1;while(m--){int l,r;l=I(),r=I(); splay(root,find(root,l));splay(T[root].ch[1],find(root,r+2)); T[T[T[root].ch[1]].ch[0]].rev^=1;}out(root);return 0;}
优化
#define g() (W==C&&(C=(W=BB)+fread(BB,1,1<<15,stdin),W==C)?EOF:*W++) char BB[1<<15],*W=BB,*C=BB; int I(){int x=0,f=1;char ch=g();for(;ch<'0'||ch>'9';ch=g())if(ch=='-')f=-1; for(;'0'<=ch&&ch<='9';ch=g())x=(x<<3)+(x<<1)+(ch^48);return x*f;} void outint(int x){if(x>=10) outint(x/10);putchar(x%10+'0');}
LCT
#include<cstdio> #include<iostream> #define ll long long #define K inline using namespace std; #define g() (W==C&&(C=(W=BB)+fread(BB,1,1<<15,stdin),W==C)?EOF:*W++) char BB[1<<15],*W=BB,*C=BB; int I(){int x=0,f=1;char ch=g();for(;ch<'0'||ch>'9';ch=g())if(ch=='-')f=-1; for(;'0'<=ch&&ch<='9';ch=g())x=(x<<3)+(x<<1)+(ch^48);return x*f;} #define lc ch[x][0] #define rc ch[x][1] #define N 300005 int ch[N][2],f[N],rev[N],sum[N],val[N],n,m; K bool get(int x){return ch[f[x]][1]==x;} K bool isroot(int x){return ch[f[x]][0]!=x&&ch[f[x]][1]!=x;} K void update(int x){sum[x]=sum[lc]^sum[rc]^val[x];} K void rever(int x){rev[x]^=1;swap(lc,rc);} K void pushdown(int x){if(rev[x]){if(lc)rever(lc);if(rc)rever(rc);rev[x]=0;}} K void pd(int x){if(!isroot(x))pd(f[x]);pushdown(x);} K void rotate(int x){int y=f[x],z=f[y],w=get(x); f[x]=z;if(!isroot(y))ch[z][get(y)]=x; ch[y][w]=ch[x][w^1];f[ch[y][w]]=y; ch[x][w^1]=y;f[y]=x;update(y);update(x);} K void splay(int x){pd(x);for(int fa=f[x];!isroot(x);rotate(x),fa=f[x]) if(!isroot(fa))rotate((get(x)==get(fa))?fa:x);} K void access(int x){for(int y=0;x;y=x,x=f[x])splay(x),rc=y,update(x);} K void make(int x){access(x);splay(x);rever(x);} K int find(int x){access(x);splay(x);while(lc)x=lc;return x;} K void split(int x,int y){make(x);access(y);splay(y);} K void link(int x,int y){make(x);f[x]=y;} K void cut(int x,int y){split(x,y);f[x]=ch[y][0]=0;update(y);} int main(){n=I();m=I();for(int i=1;i<=n;i++)val[i]=I(); while(m--){int opt=I(),x=I(),y=I(); if(opt==0)split(x,y),printf("%d\n",sum[y]); if(opt==1)if(find(x)!=find(y))link(x,y); if(opt==2)if(find(x)==find(y))cut(x,y); if(opt==3)access(x),splay(x),val[x]=y,update(x);} return 0;}
ACouto
#include <bits/stdc++.h> #define m(a) memset(a,0,sizeof(a)) #define MAXN 10505 using namespace std; string S[155]; struct acauto{ int ch[MAXN][26],l[MAXN],f[MAXN],sz,k,v[MAXN]; acauto(){m(ch);m(l);m(f);m(v);sz=1;k=0;} void insert(string &str){int n=0,p=0; while(n<str.size()){int x=str[n++]-'a'; if(!ch[p][x])ch[p][x]=sz++; p=ch[p][x];}v[p]=++k;} void getfail(){queue<int> q; for(int i=0;i<26;i++)if(ch[0][i])q.push(ch[0][i]); while(!q.empty()){int p=q.front(),t=f[p];q.pop(); for(int i=0;i<26;i++){int u=ch[p][i]; if(!u){ch[p][i]=ch[t][i];continue;} q.push(u);f[u]=ch[t][i];l[u]=v[f[u]]?f[u]:l[f[u]];}}} void find(string &str){int cnt[MAXN]={0},n=0,p=0,maxn=-1; while(n<str.size()){int x=str[n++]-'a';p=ch[p][x]; if(v[p])cnt[v[p]]++;int t=p; while(l[t]){t=l[t];if(v[t])cnt[v[t]]++;}} for(int i=1;i<=k;i++)maxn=max(maxn,cnt[i]); cout<<maxn<<endl;for(int i=1;i<=k;i++)if(cnt[i]==maxn)cout<<S[i]<<endl;} }; int main(){ios::sync_with_stdio(false); while(1){int n;acauto ac;string s;cin>>n;if(!n)break; for(int i=1;i<=n;i++)cin>>S[i],ac.insert(S[i]); ac.getfail();cin>>s;ac.find(s);}return 0;}
多项式乘法
#include<bits/stdc++.h> #define N 3000000 #define pi acos(-1) using namespace std; int n,m,l,log_2,rev[N]; struct o{double r,i;o(){} o(double a,double b):r(a),i(b){} o operator +(const o &a)const{return o(a.r+r,a.i+i);} o operator -(const o &a)const{return o(r-a.r,i-a.i);} o operator *(const o &a)const{return o(r*a.r-i*a.i,r*a.i+i*a.r);} }a[N],b[N],w[N]; inline void fft(o *a,int n,int f){ for(int i=0;i<n;i++)if(i<rev[i])swap(a[i],a[rev[i]]); for(int i=1;i<n;i<<=1){o wn(cos(pi/i),f*sin(pi/i)); for(int j=1;j<i;j++)w[j]=w[j-1]*wn; for(int j=0;j<n;j+=i<<1){o *x=a+j,*y=a+i+j,p; for(int k=0;k<i;k++)p=w[k]*y[k],y[k]=x[k]-p,x[k]=x[k]+p;}}} #define g() (W==C&&(C=(W=BB)+fread(BB,1,1<<15,stdin),W==C)?EOF:*W++) char BB[1<<15],*W=BB,*C=BB; int I(){int x=0,f=1;char ch=g();for(;ch<'0'||ch>'9';ch=g())if(ch=='-')f=-1; for(;'0'<=ch&&ch<='9';ch=g())x=(x<<3)+(x<<1)+(ch^48);return x*f;} void out(int x){if(x>=10)out(x/10);putchar(x%10+'0');} int main(){w[0]=o(1,0);n=I(),m=I(); for(int i=0;i<=n;i++)a[i].r=I();for(int i=0;i<=m;i++)b[i].r=I(); for(l=1;l<=n+m;l<<=1)log_2++;log_2--; for(int i=1;i<l;i++)rev[i]=(rev[i>>1]>>1)|((i&1)<<log_2); fft(a,l,1),fft(b,l,1);for(int i=0;i<l;i++)a[i]=a[i]*b[i]; fft(a,l,-1);for(int i=0;i<=n+m;i++)out((int)(a[i].r/l+0.5)),putchar(' ');return 0;}
后缀自动机
#include <cstdio> #include <cstring> using namespace std; #define N 2000010 int cnt,np,tp;char s[N]; int l[N],r[N],fa[N],ch[N][26],v[N],in[N],g[N]; #define cint register int #define f(a,b) for(cint i=a;i<=b;i++) int max(int a,int b){return a>b?a:b;} inline void insert(int c){int x=np,y;l[np=++cnt]=l[x]+1;r[np]=1; while(x&&!ch[x][c]) ch[x][c]=np,x=fa[x]; y=ch[x][c];if(!y){ch[x][c]=np;return;}if(l[y]==l[x]+1)fa[np]=y; else{int nq=++cnt;l[nq]=l[x]+1;memcpy(ch[nq],ch[y],sizeof(ch[y])); fa[nq]=fa[y],fa[y]=fa[np]=nq;while(ch[x][c]==y)ch[x][c]=nq,x=fa[x];}} int main() {scanf("%s",s);int n=strlen(s);long long ans=0; f(0,n-1)insert(s[i]-'a');f(1,cnt)++in[fa[i]];f(1,cnt)if(!in[i])v[++tp]=i; while(tp){int x=v[tp--];g[x]+=r[x]; if(g[x]>1)ans=max(ans,1ll*g[x]*l[x]); g[fa[x]]+=g[x];if(!--in[fa[x]]) v[++tp]=fa[x];} printf("%lld",ans);return 0;}