突然觉得应该攒一些模版了……这样以后就可以方便的抄了
#include<cstdio> #include<algorithm> using namespace std; int en,pre[30005],segn,n,q,top[30005],id[30005],data[30005],fa[30005],son[30005],siz[30005],dep[30005],h[30005]; char ask[10]; struct Edge{ int b,next; }e[60005]; struct SegTree{ int l,r,v,sum; }tree[120005]; void add(int sa,int sb){ e[++en].b=sb; e[en].next=h[sa]; h[sa]=en; } void Build(int root,int l,int r){ tree[root].l=l; tree[root].r=r; if(l==r){ tree[root].v=data[pre[l]]; tree[root].sum=data[pre[l]]; return; } int mid=(l+r)/2; Build(root*2,l,mid); Build(root*2+1,mid+1,r); tree[root].v=max(tree[root*2].v,tree[root*2+1].v); tree[root].sum=tree[root*2].sum+tree[root*2+1].sum; } void Update(int root,int pos,int val){ if(tree[root].l==tree[root].r){ tree[root].v+=val; tree[root].sum+=val; return; } int mid=(tree[root].l+tree[root].r)/2; if(pos<=mid)Update(root*2,pos,val); if(pos>mid)Update(root*2+1,pos,val); tree[root].v=max(tree[root*2].v,tree[root*2+1].v); tree[root].sum=tree[root*2].sum+tree[root*2+1].sum; } int QueryMax(int root,int l,int r){ if(tree[root].l>=l && tree[root].r<=r){ return tree[root].v; } int mid=(tree[root].l+tree[root].r)/2,ans=-2147483647; if(l<=mid)ans=max(ans,QueryMax(root*2,l,r)); if(r>mid)ans=max(ans,QueryMax(root*2+1,l,r)); return ans; } int QuerySum(int root,int l,int r){ if(tree[root].l>=l && tree[root].r<=r){ return tree[root].sum; } int mid=(tree[root].l+tree[root].r)/2,ans=0; if(l<=mid)ans+=QuerySum(root*2,l,r); if(r>mid)ans+=QuerySum(root*2+1,l,r); return ans; } void dfs1(int u,int father,int deep){ fa[u]=father; dep[u]=deep; siz[u]=1; son[u]=0; for(int i=h[u];i;i=e[i].next){ int v=e[i].b; if(v==father)continue; dfs1(v,u,deep+1); siz[u]+=siz[v]; if(siz[v]>siz[son[u]]){ son[u]=v; } } } void dfs2(int u,int ux){ top[u]=ux; id[u]=++segn; pre[segn]=u; if(son[u])dfs2(son[u],ux); else return; for(int i=h[u];i;i=e[i].next){ int v=e[i].b; if(v!=son[u] && v!=fa[u]){dfs2(v,v);} } } int AskMax(int u,int v){ int f1=top[u],f2=top[v],ans=-2147483647; while(f1!=f2){ if(dep[f1]<dep[f2]){ swap(u,v); swap(f1,f2); } ans=max(ans,QueryMax(1,id[f1],id[u])); u=fa[f1]; f1=top[u]; } if(dep[u]>dep[v]){ swap(u,v); } ans=max(ans,QueryMax(1,id[u],id[v])); return ans; } int AskSum(int u,int v){ int f1=top[u],f2=top[v],ans=0; while(f1!=f2){ if(dep[f1]<dep[f2]){ swap(u,v); swap(f1,f2); } ans+=QuerySum(1,id[f1],id[u]); u=fa[f1]; f1=top[u]; } if(dep[u]>dep[v]){ swap(u,v); } ans+=QuerySum(1,id[u],id[v]); return ans; } int main(){ freopen("1036.in","r",stdin); freopen("1036.out","w",stdout); scanf("%d",&n); for(int i=1;i<n;i++){ int sa,sb; scanf("%d %d",&sa,&sb); add(sa,sb); add(sb,sa); } for(int i=1;i<=n;i++){ scanf("%d",&data[i]); } dfs1(1,0,1); dfs2(1,1); Build(1,1,n); scanf("%d",&q); while(q--){ int sa,sb; scanf("%s %d %d",ask,&sa,&sb); if(ask[0]=='C'){Update(1,id[sa],sb-data[sa]);data[sa]=sb;} if(ask[1]=='M'){printf("%d\n",AskMax(sa,sb));} if(ask[1]=='S'){printf("%d\n",AskSum(sa,sb));} } return 0; }
#include<cstdio> #include<cstring> #include<queue> using namespace std; struct AC_Trie{ int fail,next[26],key; AC_Trie(){fail=0;key=0;} }tree[500005]; int n,cnt=1; char s[1000005]; queue<int> Q; void Ins(){ int len=strlen(s),j=1; for(int i=0;i<len;i++){ int p=s[i]-'a'; if(tree[j].next[p]==0)tree[j].next[p]=++cnt; j=tree[j].next[p]; } tree[j].key++; } void BFS(){ Q.push(1); while(!Q.empty()){ int u=Q.front(); Q.pop(); for(int i=0;i<=25;i++){ int v=tree[u].next[i]; if(v==0)continue; Q.push(v); if(u==1){ tree[v].fail=1; continue; } int p=tree[u].fail; while(p){ if(tree[p].next[i]){ tree[v].fail=tree[p].next[i]; break; } p=tree[p].fail; } if(!p)tree[v].fail=1; } } } int GetAns(){ int len=strlen(s),ans=0,j=1; for(int i=0;i<len;i++){ int p=s[i]-'a'; while(tree[j].next[p]==0 && j!=1)j=tree[j].fail; j=tree[j].next[p]; if(j==0)j=1; int q=j; while(q!=1 && tree[q].key!=-1){ ans+=tree[q].key; tree[q].key=-1; q=tree[q].fail; } } return ans; } int main(){ freopen("2222.in","r",stdin); freopen("2222.out","w",stdout); scanf("%d",&n); for(int i=1;i<=n;i++){ scanf("%s",s); Ins(); } BFS(); scanf("%s",s); printf("%d\n",GetAns()); return 0; }
#include<cstdio> #include<algorithm> using namespace std; int n,a[1000005],m; struct Node{ int v,mx,sum,lx,rx,siz,tag,rev; Node *ch[2],*fa; Node(int val,Node *fat); void Pushdown(); void Pushup(); }*root,*Null; Node::Node(int val=0,Node *fat=Null){ ch[0]=ch[1]=Null; fa=fat; v=sum=mx=val; tag=rev=0; siz=1; if(v>=0)lx=rx=v; else lx=rx=0; } void Node::Pushdown(){ if(tag){ tag=rev=0; if(ch[0]!=Null){ch[0]->tag=1;ch[0]->sum=ch[0]->siz*v;ch[0]->v=v;} if(ch[1]!=Null){ch[1]->tag=1;ch[1]->sum=ch[1]->siz*v;ch[1]->v=v;} if(v>=0){ if(ch[0]!=Null){ch[0]->lx=ch[0]->mx=ch[0]->rx=v*ch[0]->siz;} if(ch[1]!=Null){ch[1]->lx=ch[1]->mx=ch[1]->rx=v*ch[1]->siz;} } else { if(ch[0]!=Null){ch[0]->mx=v;ch[0]->lx=ch[0]->rx=0;} if(ch[1]!=Null){ch[1]->mx=v;ch[1]->lx=ch[1]->rx=0;} } } if(rev){ rev=0; if(ch[0]!=Null)ch[0]->rev^=1; if(ch[1]!=Null)ch[1]->rev^=1; swap(ch[0]->ch[0],ch[0]->ch[1]); swap(ch[1]->ch[0],ch[1]->ch[1]); swap(ch[0]->lx,ch[0]->rx); swap(ch[1]->lx,ch[1]->rx); } } void Node::Pushup(){ siz=ch[0]->siz+ch[1]->siz+1; sum=ch[0]->sum+ch[1]->sum+v; mx=max(ch[0]->mx,ch[1]->mx); mx=max(mx,ch[0]->rx+v+ch[1]->lx); lx=max(ch[0]->lx,ch[0]->sum+v+ch[1]->lx); rx=max(ch[1]->rx,ch[1]->sum+v+ch[0]->rx); } void Rotate(Node *x,int kind){ Node *y=x->fa,*z=y->fa; y->ch[!kind]=x->ch[kind]; if(x->ch[kind]!=Null)x->ch[kind]->fa=y; x->fa=z; if(z!=Null)z->ch[z->ch[1]==y]=x; y->fa=x; x->ch[kind]=y; y->Pushup(); x->Pushup(); } void Splay(Node *x,Node *place){ while(x->fa!=place){ Node *y=x->fa,*z=y->fa; if(z==Null || z==place)Rotate(x,y->ch[0]==x); else { if(y->ch[0]==x && z->ch[0]==y){Rotate(y,1);Rotate(x,1);} else if(y->ch[0]==x && z->ch[1]==y){Rotate(x,1);Rotate(x,0);} else if(y->ch[1]==x && z->ch[0]==y){Rotate(x,0);Rotate(x,1);} else {Rotate(y,0);Rotate(x,0);} } } if(place==Null)root=x; } Node *Find(Node *splay,int k){ splay->Pushdown(); if(splay->ch[0]->siz+1==k)return splay; if(splay->ch[0]->siz>=k)return Find(splay->ch[0],k); return Find(splay->ch[1],k-1-splay->ch[0]->siz); } Node *Split(int pos,int tot){ Node *x=Find(root,pos); Splay(x,Null); Node *y=Find(root,pos+tot+1); Splay(y,root); return y->ch[0]; } Node *Build(int l,int r){ if(l>r)return Null; int mid=l+r>>1; Node *splay=new Node(a[mid],Null); splay->ch[0]=Build(l,mid-1); if(splay->ch[0]!=Null)splay->ch[0]->fa=splay; splay->ch[1]=Build(mid+1,r); if(splay->ch[1]!=Null)splay->ch[1]->fa=splay; splay->Pushup(); return splay; } void Insert(int pos,int tot){ Node *x=Find(root,pos+1),*y=Find(root,pos+2); Splay(x,Null);Splay(y,root); y->ch[0]=Build(1,tot); if(y->ch[0]!=Null)y->ch[0]->fa=y; y->Pushup(); x->Pushup(); } Node *GetNull(){ Node *p=new Node(0,Null); p->fa=p->ch[0]=p->ch[1]=p; p->mx=p->v=-1000000000; p->rev=p->tag=p->siz=p->sum=p->lx=p->rx=0; return p; } void Build_First(){ Null=GetNull(); a[1]=-1000000000; a[n+2]=-1000000000; root=Build(1,n+2); } void Del_Tree(Node *splay){ if(splay==Null)return; splay->Pushdown(); Del_Tree(splay->ch[0]); Del_Tree(splay->ch[1]); if(splay->ch[0]!=Null)delete splay->ch[0]; if(splay->ch[1]!=Null)delete splay->ch[1]; splay->ch[0]=Null; splay->ch[1]=Null; splay->Pushup(); } void Delete(int pos,int val){ Node *seq=Split(pos,val),*fat=seq->fa; Del_Tree(seq); if(seq!=Null)delete seq; fat->ch[0]=Null; fat->Pushup(); fat->fa->Pushup(); } void MakeSame(int pos,int tot,int val){ Node *seq=Split(pos,tot),*fat=seq->fa; seq->tag=1; seq->sum=seq->siz*val; seq->v=val; if(val>=0)seq->lx=seq->rx=seq->mx=seq->siz*val; else seq->lx=seq->rx=0,seq->mx=val; fat->Pushup(); fat->fa->Pushup(); } void Reverse(int pos,int tot){ Node *seq=Split(pos,tot),*fat=seq->fa; if(!seq->tag){ seq->rev^=1; swap(seq->ch[0],seq->ch[1]); swap(seq->lx,seq->rx); fat->Pushup(); fat->fa->Pushup(); } } int GetSum(int pos,int tot){ Node *seq=Split(pos,tot); return seq->sum; } int main(){ freopen("1500.in","r",stdin); freopen("1500.out","w",stdout); scanf("%d %d",&n,&m); for(int i=2;i<=n+1;i++)scanf("%d",&a[i]); Build_First(); for(int i=1;i<=m;i++){ char s[10]; scanf("%s",s); if(s[0]=='I'){ int pos,tot; scanf("%d %d",&pos,&tot); for(int i=1;i<=tot;i++)scanf("%d",&a[i]); Insert(pos,tot); } if(s[0]=='D'){ int pos,tot; scanf("%d %d",&pos,&tot); Delete(pos,tot); } if(s[0]=='M' && s[2]=='K'){ int pos,tot,val; scanf("%d %d %d",&pos,&tot,&val); MakeSame(pos,tot,val); } if(s[0]=='M' && s[2]=='X'){ printf("%d\n",root->mx); } if(s[0]=='R'){ int pos,tot; scanf("%d %d",&pos,&tot); Reverse(pos,tot); } if(s[0]=='G'){ int pos,tot; scanf("%d %d",&pos,&tot); printf("%d\n",GetSum(pos,tot)); } } return 0; }
#include<cstdio> #include<cstring> #include<algorithm> using namespace std; char s[500005]; int n,rank[500005],rank2[500005],height[500005],sa[500005],rmq[500005][20],ws[500005],wv[500005],er[20],log2[500005]; int cmp(int *r,int a,int b,int l){return (r[a]==r[b])&(r[a+l]==r[b+l]);} void GetSA(char *r,int *sa,int n,int m){ int i,j,p,*x=rank,*y=rank2,*t; for(i=0;i<m;i++)ws[i]=0; for(i=0;i<n;i++)ws[x[i]=r[i]]++; for(i=1;i<m;i++)ws[i]+=ws[i-1]; for(i=n-1;i>=0;i--)sa[--ws[x[i]]]=i; for(j=p=1;p<n;j*=2,m=p){ for(p=0,i=n-j;i<n;i++)y[p++]=i; for(i=0;i<n;i++)if(sa[i]>=j)y[p++]=sa[i]-j; for(i=0;i<m;i++)ws[i]=0; for(i=0;i<n;i++)ws[wv[i]=x[y[i]]]++; for(i=1;i<m;i++)ws[i]+=ws[i-1]; for(i=n-1;i>=0;i--)sa[--ws[wv[i]]]=y[i]; for(t=x,x=y,y=t,x[sa[0]]=0,p=i=1;i<n;i++)x[sa[i]]=cmp(y,sa[i-1],sa[i],j)?p-1:p++; } } void CalHeight(char *r,int *sa,int n){ int i,j,k=0; for(i=1;i<=n;i++)rank[sa[i]]=i; for(i=0;i<n;height[rank[i++]]=k)for(k?k--:0,j=sa[rank[i]-1];r[i+k]==r[j+k];k++); } void RMQ(){ int i,j; er[0]=1; for(i=1;i<20;i++)er[i]=er[i-1]<<1; log2[0]=-1; for(i=1;i<=n;i++)log2[i]=(i&(i-1))?log2[i-1]:log2[i-1]+1; for(i=1;i<=n;i++)rmq[i][0]=height[i]; for(j=1;j<20;j++)for(i=1;i+er[j-1]-1<=n;i++)rmq[i][j]=min(rmq[i][j-1],rmq[i+er[j-1]][j-1]); } int LCP(int a,int b){ int x=rank[a],y=rank[b],t; if(x>y)t=x,x=y,y=t; x++; int k=log2[y-x+1]; return min(rmq[x][k],rmq[y-er[k]+1][k]); } int main(){ freopen("suffix.in","r",stdin); freopen("suffix.out","w",stdout); scanf("%s",s); n=strlen(s); s[n]=0; GetSA(s,sa,n+1,128); CalHeight(s,sa,n); RMQ(); int q; scanf("%d",&q); for(int i=1;i<=q;i++){ int sa,sb; scanf("%d %d",&sa,&sb); printf("%d\n",LCP(sa,sb)); } return 0; }
#include<cstdio> #include<algorithm> #include<cstdlib> #include<cmath> #include<cstring> using namespace std; const double Pi=2*asin(1); const int NUM_SIZE=100005; int An,Bn,Cn,Rev[NUM_SIZE*3],Step,n; struct Complex{ double a,b; Complex(double as=0.0,double bs=0.0){a=as;b=bs;} friend Complex operator+(Complex a,Complex b){return Complex(a.a+b.a,a.b+b.b);} friend Complex operator-(Complex a,Complex b){return Complex(a.a-b.a,a.b-b.b);} friend Complex operator*(Complex a,Complex b){return Complex(a.a*b.a-a.b*b.b,b.a*a.b+a.a*b.b);} friend Complex operator/(Complex a,Complex b){return Complex((a.a*b.a+a.b*b.b)/(b.a*b.a+b.b*b.b),(b.a*a.b-a.a*b.b)/(b.a*b.a+b.b*b.b));} double Mod(){return sqrt(a*a+b*b);} }A[NUM_SIZE*3],B[NUM_SIZE*3],C[NUM_SIZE*3]; template<typename T>void Read(T &x){ int flag=1; char ch; while((ch=getchar())<'0' || ch>'9')if(ch=='-')flag=-1; x=ch-'0'; while((ch=getchar())>='0' && ch<='9')x=x*10+ch-'0'; x*=flag; } void FFT(Complex *x,int flag){ for(int i=0;i<n;i++)if(i<Rev[i])swap(x[i],x[Rev[i]]); for(int k=1;k<n;k<<=1){ Complex wk=Complex(cos(Pi/k),flag*sin(Pi/k)); for(int i=0;i<n;i+=k<<1){ Complex wkj=Complex(1.0,0.0); for(int j=0;j<k;j++){ Complex a=x[i+j],b=x[i+j+k]*wkj; x[i+j]=a+b; x[i+j+k]=a-b; wkj=wkj*wk; } } } if(flag==-1){for(int i=0;i<n;i++)x[i].a/=n;} } int main(){ freopen("34.in","r",stdin); freopen("34.out","w",stdout); Read(An);Read(Bn); An++;Bn++; Cn=An+Bn-1; for(int i=0;i<An;i++)Read(A[i].a); for(int i=0;i<Bn;i++)Read(B[i].a); for(n=1,Step=0;n<Cn;Step++,n<<=1); for(int i=0;i<n;i++)Rev[i]=(Rev[i>>1]>>1)|((i&1)<<(Step-1)); FFT(A,1); FFT(B,1); for(int i=0;i<n;i++)C[i]=A[i]*B[i]; FFT(C,-1); for(int i=0;i<Cn;i++)printf("%d ",(int)(C[i].a+0.5)); putchar('\n'); return 0; }