模板大全

目录

1.最小生成树

2.并查集

3.最大流

4.费用流

5.树链剖分

6.左偏树

7.矩阵加速

8.树状数组1(单点加法,区间和)

9.FFT a*b

10.单源最短路径

11.三分法

12.VEB树

13.线段树(区间乘法,区间加法,区间和)

14.KMP

15.线性筛素数

16.负环

17.Splay

18.优化

19.LCT

20.ACouto

21.多项式乘法

22.后缀自动机

 

 

最小生成树


 

#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;}

 

posted @ 2017-11-26 12:07  yodel  阅读(349)  评论(0编辑  收藏  举报