嗯……这些ID都是我的
Lvat2000
Lvat_s
A_Star
Lvat_Violet
DreamPublisher
SkyChecker
OI_Endless
SnowSword
Initialize
好像就这些了……也许我自己忘了一些ID……
嗯……这些ID都是我的
Lvat2000
Lvat_s
A_Star
Lvat_Violet
DreamPublisher
SkyChecker
OI_Endless
SnowSword
Initialize
好像就这些了……也许我自己忘了一些ID……
无语了……
参考hzwer的题解,我自己没想出来……
具体就是先搞一遍LCA,再分三种情况判断
详见hzwer题解:传送门
判定ROOT时居然写了if(ROOT=x)简直爆炸
没救了
#include<cstdio> #include<algorithm> using namespace std; int h[100005],en,fa[100005][18],data[100005],dfn,L[100005],R[100005],pre[100005],ROOT=1,bits[20],dep[100005],n,q; struct Edge{ int b,next; }e[200005]; struct SegTree{ int l,r,mn; }tree[400005]; void Pushup(int root){ tree[root].mn=min(tree[root*2].mn,tree[root*2+1].mn); } void Build(int root,int l,int r){ tree[root].l=l; tree[root].r=r; if(l==r){ tree[root].mn=data[pre[l]]; return; } int mid=l+r>>1; Build(root*2,l,mid); Build(root*2+1,mid+1,r); Pushup(root); } void Change(int root,int pos,int val){ if(tree[root].l==tree[root].r){ tree[root].mn=val; return; } int mid=tree[root].l+tree[root].r>>1; if(pos<=mid)Change(root*2,pos,val); if(pos>mid)Change(root*2+1,pos,val); Pushup(root); } int GtMn(int root,int l,int r){ if(l>r)return 2100000000; if(tree[root].l>=l && tree[root].r<=r){ return tree[root].mn; } int mid=tree[root].l+tree[root].r>>1,ans=2100000000; if(l<=mid)ans=min(ans,GtMn(root*2,l,r)); if(r>mid)ans=min(ans,GtMn(root*2+1,l,r)); return ans; } void AddEdge(int sa,int sb){ e[++en].b=sb; e[en].next=h[sa]; h[sa]=en; } void dfs(int u){ L[u]=++dfn; pre[dfn]=u; for(int i=1;i<=18;i++){ if(bits[i]<=dep[u])fa[u][i]=fa[fa[u][i-1]][i-1]; else break; } for(int i=h[u];i;i=e[i].next){ int v=e[i].b; dep[v]=dep[u]+1; fa[v][0]=u; dfs(v); } R[u]=dfn; } int main(){ freopen("3306.in","r",stdin); freopen("3306.out","w",stdout); bits[0]=1; for(int i=1;i<=18;i++)bits[i]=bits[i-1]<<1; scanf("%d %d",&n,&q); //printf("%d %d\n",n,q); for(int i=1;i<=n;i++){ int u; scanf("%d %d",&u,&data[i]); //printf("%d %d\n",u,data[i]); if(u)AddEdge(u,i); } dfs(ROOT=1); Build(1,1,n); for(int i=1;i<=q;i++){ char s[5]; int x,y; scanf("%s",s); if(s[0]=='V'){ scanf("%d %d",&x,&y); Change(1,L[x],y); } if(s[0]=='E'){ scanf("%d",&x); ROOT=x; } if(s[0]=='Q'){ scanf("%d",&x); if(ROOT==x){printf("%d\n",tree[1].mn);continue;} if(L[x]<=L[ROOT] && R[x]>=R[ROOT]){ y=ROOT; int deep=dep[y]-dep[x]-1; for(int i=0;i<=18;i++){ if(bits[i]&deep)y=fa[y][i]; } printf("%d\n",min(GtMn(1,1,L[y]-1),GtMn(1,R[y]+1,n))); continue; } printf("%d\n",GtMn(1,L[x],R[x])); } } return 0; }
因为一棵树的子树一定在dfs序上是连续的
所以直接修改就行了
#include<cstdio> #include<algorithm> using namespace std; struct Edge{ int b,next; }e[1000005]; struct SegTree{ int l,r; long long tag,sum; }tree[1000005]; int n,q,en,cnt,top[400005],id[400005],pre[400005],dep[400005],son[400005],h[400005],siz[400005],fa[400005]; void AddEdge(int sa,int sb){ e[++en].b=sb; e[en].next=h[sa]; h[sa]=en; } void Pushdown(int root){ if(tree[root].tag){ tree[root*2].tag+=tree[root].tag; tree[root*2].sum+=tree[root].tag*(tree[root*2].r-tree[root*2].l+1); tree[root*2+1].tag+=tree[root].tag; tree[root*2+1].sum+=tree[root].tag*(tree[root*2+1].r-tree[root*2+1].l+1); tree[root].tag=0; } } void Pushup(int root){ tree[root].sum=tree[root*2].sum+tree[root*2+1].sum; } void Build(int root,int l,int r){ tree[root].l=l; tree[root].r=r; if(l==r){ tree[root].sum=0; return; } int mid=(l+r)/2; Build(root*2,l,mid); Build(root*2+1,mid+1,r); tree[root].sum=tree[root*2].sum+tree[root*2+1].sum; } void Add(int root,int l,int r,long long v){ if(tree[root].l>=l && tree[root].r<=r){ tree[root].tag+=v; tree[root].sum+=v*(tree[root].r-tree[root].l+1); return; } Pushdown(root); int mid=tree[root].l+tree[root].r>>1; if(l<=mid)Add(root*2,l,r,v); if(r>mid)Add(root*2+1,l,r,v); Pushup(root); } long long Sum(int root,int l,int r){ if(tree[root].l>=l && tree[root].r<=r){ return tree[root].sum; } Pushdown(root); int mid=tree[root].l+tree[root].r>>1; long long ans=0; if(l<=mid)ans+=Sum(root*2,l,r); if(r>mid)ans+=Sum(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]=++cnt; pre[cnt]=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);} } } void AddLine(int u,int v,long long val){ int f1=top[u],f2=top[v]; while(f1!=f2){ if(dep[f1]<dep[f2]){swap(u,v);swap(f1,f2);} Add(1,id[f1],id[u],val); u=fa[f1]; f1=top[u]; } if(dep[u]>dep[v])swap(u,v); //printf("%d %d\n",id[u],id[v]); Add(1,id[u],id[v],val); } int main(){ freopen("2836.in","r",stdin); freopen("2836.out","w",stdout); scanf("%d",&n); for(int i=1;i<n;i++){ int u,v; scanf("%d %d",&u,&v); AddEdge(u+1,v+1); AddEdge(v+1,u+1); } Build(1,1,n); dfs1(1,0,1); dfs2(1,1); scanf("%d",&q); while(q--){ int u,v; long long val; char s[3]; scanf("%s",s); if(s[0]=='A'){ scanf("%d %d %lld",&u,&v,&val); AddLine(u+1,v+1,val); } if(s[0]=='Q'){ scanf("%d",&u); //printf("IS:%d %d %d\n",id[u+1],siz[u+1],u+1); printf("%lld\n",Sum(1,id[u+1],id[u+1]+siz[u+1]-1)); } } return 0; }
LCT
#include<cstdio> #include<algorithm> #include<map> using namespace std; int n,m,c,t,have[10005][105]; map<int,int> Mp[1000005]; struct Node{ int rev; Node *ch[2],*fa; Node(Node *fat); void Pushdown(); }*root[1000005],*Null; Node::Node(Node *fat=Null){ ch[0]=ch[1]=Null; fa=fat; rev=0; } Node *GetNull(){ Node *re=new Node(re); re->rev=0; re->ch[0]=re->fa=re->ch[1]=re; return re; } void Node::Pushdown(){ if(rev){ if(ch[0]!=Null)ch[0]->rev^=1; if(ch[1]!=Null)ch[1]->rev^=1; swap(ch[0],ch[1]); rev=0; } } int Notroot(Node *x){ return (x->fa->ch[0]==x)||(x->fa->ch[1]==x); } void Prepare(Node *x){ if(Notroot(x))Prepare(x->fa); x->Pushdown(); } 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(Notroot(y))z->ch[z->ch[1]==y]=x; y->fa=x; x->ch[kind]=y; } void Splay(Node *x){ Prepare(x); while(Notroot(x)){ Node *y=x->fa,*z=y->fa; if(!Notroot(y))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);} } } } void Access(Node *x){ for(Node *y=Null;x!=Null;y=x,x=x->fa){Splay(x);x->ch[1]=y;} } void Makeroot(Node *x){ Access(x); Splay(x); x->rev^=1; } void Link(Node *u,Node *v){ Makeroot(u); u->fa=v; } void Cut(Node *u,Node *v){ Makeroot(u); Access(v); Splay(v); if(v->ch[0]==u){v->ch[0]=Null;u->fa=Null;} } Node *Find(Node *x){ Access(x); Splay(x); while(x->ch[0]!=Null)x=x->ch[0]; return x; } int GetPoint(int x,int y){ return x+(y-1)*n; } Node *ToLct(int x,int c){ return root[GetPoint(x,c)]; } void Change(int x,int y,int z){ int Tok=Mp[x][y]; if(Tok==0){puts("No such cable.");return;} if(Tok==z){puts("Already owned.");return;} //printf("%d %d\n",have[x][z],have[y][z]); if(have[x][z]==2 || have[y][z]==2){puts("Forbidden: monopoly.");return;} Node *u1=ToLct(x,Tok),*u2=ToLct(x,z),*v1=ToLct(y,Tok),*v2=ToLct(y,z); //printf("%d %d\n",Find(u2),Find(v2)); if(Find(u2)==Find(v2)){puts("Forbidden: redundant.");return;} Cut(u1,v1); have[x][Tok]--; have[y][Tok]--; have[x][z]++; have[y][z]++; Mp[x][y]=z; Link(u2,v2); puts("Sold."); } int main(){ freopen("3651.in","r",stdin); freopen("3651.out","w",stdout); scanf("%d %d %d %d",&n,&m,&c,&t); Null=GetNull(); for(int i=1;i<=n*c;i++){root[i]=new Node(Null);} //printf("%d %d %d %d\n",Null,Null->ch[0],Null->ch[1],Null->fa); for(int i=1;i<=m;i++){ int s1,s2,k; scanf("%d %d %d",&s1,&s2,&k); if(s1>s2)swap(s1,s2); have[s1][k]++; have[s2][k]++; Mp[s1][s2]=k; //printf("%d %d %d | %d %d N*C:%d\n",s1,s2,k,GetPoint(s1,k),GetPoint(s2,k),n*c); Node *x=ToLct(s1,k),*y=ToLct(s2,k); Link(x,y); } for(int i=1;i<=t;i++){ int s1,s2,k; scanf("%d %d %d",&s1,&s2,&k); if(s1>s2)swap(s1,s2); Change(s1,s2,k); } return 0; }
LCT直接上
记录子树的大小
#include<cstdio> #include<algorithm> using namespace std; int n,m,Next[200005]; struct Node{ int siz,rev; Node *ch[2],*fa; Node(Node *fat); void Pushup(); void Pushdown(); }*root[200005],*Null; Node::Node(Node *fat){ ch[0]=ch[1]=Null; fa=fat; siz=1; rev=0; } void Node::Pushup(){ siz=1; if(ch[0]!=Null)siz+=ch[0]->siz; if(ch[1]!=Null)siz+=ch[1]->siz; } void Node::Pushdown(){ if(rev){ if(ch[0]!=Null)ch[0]->rev^=1; if(ch[1]!=Null)ch[1]->rev^=1; swap(ch[0],ch[1]); rev=0; } } int Notroot(Node *x){ return (x->fa->ch[0]==x)||(x->fa->ch[1]==x); } void Prepare(Node *x){ if(Notroot(x))Prepare(x->fa); x->Pushdown(); } 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(Notroot(y))z->ch[z->ch[1]==y]=x; y->fa=x; x->ch[kind]=y; y->Pushup(); x->Pushup(); } void Splay(Node *x){ Prepare(x); while(Notroot(x)){ Node *y=x->fa,*z=y->fa; if(!Notroot(y)){Rotate(x,y->ch[0]==x);} else { if(y->ch[1]==x && z->ch[1]==y){Rotate(y,0);Rotate(x,0);} else if(y->ch[1]==x && z->ch[0]==y){Rotate(x,0);Rotate(x,1);} else if(y->ch[0]==x && z->ch[0]==y){Rotate(y,1);Rotate(x,1);} else {Rotate(x,1);Rotate(x,0);} } } } void Access(Node *x){ for(Node *y=Null;x!=Null;y=x,x=x->fa){Splay(x);x->ch[1]=y;x->Pushup();} } void Makeroot(Node *x){ Access(x); Splay(x); x->rev^=1; } void Link(Node *x,Node *y){ Makeroot(x); x->fa=y; } void Cut(Node *x,Node *y){ Makeroot(x); Access(y); Splay(y); if(y->ch[0]==x){y->ch[0]=Null;x->fa=Null;} } Node *Find(Node *x){ Access(x); Splay(x); while(x->ch[0]!=Null)x=x->ch[0]; return x; } Node *ToLct(int x){ return root[x]; } Node *GetNull(){ Node *u=new Node(Null); u->fa=u->ch[0]=u->ch[1]=u; u->siz=0; u->rev=0; return u; } int Jump(int x){ Node *u=ToLct(x); Makeroot(ToLct(n+1)); Access(u); Splay(u); return u->ch[0]->siz; } void Change(int x,int y){ //Node *u=ToLct(x),*v=ToLct(Next[x]); //printf("Tp%d\n",Next[x]); int t=min(x+y,n+1); //printf("Tpt%d\n",t); Cut(ToLct(x),ToLct(Next[x])); Link(ToLct(x),ToLct(t)); Next[x]=t; } int main(){ freopen("2002.in","r",stdin); freopen("2002.out","w",stdout); Null=GetNull(); scanf("%d",&n); root[n+1]=new Node(Null); for(int i=1;i<=n;i++){ int tp; scanf("%d",&tp); root[i]=new Node(Null); Next[i]=min(n+1,tp+i); } for(int i=1;i<=n;i++){ Link(ToLct(i),ToLct(Next[i])); } scanf("%d",&m); for(int i=1;i<=m;i++){ int opt,x,y; scanf("%d",&opt); if(opt==1){scanf("%d",&x);printf("%d\n",Jump(x+1));} if(opt==2){scanf("%d %d",&x,&y);Change(x+1,y);} } return 0; }
Link-Cut Tree直接上……
但是因为智商原因2天才能理解+写会这个东西。
因为BZOJ爆了所以测不了。但是和hzwer的程序对拍了没拍出什么错误。。。在BZOJ上AC了
#include<cstdio> #include<algorithm> using namespace std; int n,m; struct Node{ int v,ans,rev; Node *ch[2],*fa; Node(int val,Node *fat); void Pushdown(); void Pushup(); }*root[300005],*Null; Node::Node(int val=0,Node *fat=Null){ ch[0]=ch[1]=Null; fa=fat; v=ans=val; rev=0; } void Node::Pushdown(){ if(rev){ if(ch[0]!=Null)ch[0]->rev^=1; if(ch[1]!=Null)ch[1]->rev^=1; swap(ch[0],ch[1]); rev=0; } } void Node::Pushup(){ ans=v; if(ch[0]!=Null)ans^=ch[0]->ans; if(ch[1]!=Null)ans^=ch[1]->ans; } int Notroot(Node *x){ return (x->fa->ch[0]==x)||(x->fa->ch[1]==x); } void Prepare(Node *x){ if(Notroot(x))Prepare(x->fa); x->Pushdown(); } 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(Notroot(y))z->ch[z->ch[1]==y]=x; y->fa=x; x->ch[kind]=y; y->Pushup(); x->Pushup(); } void Splay(Node *x){ Prepare(x); while(Notroot(x)){ Node *y=x->fa,*z=y->fa; if(!Notroot(y)){Rotate(x,y->ch[0]==x);} else { if(y->ch[1]==x && z->ch[1]==y){Rotate(y,0);Rotate(x,0);} else if(y->ch[1]==x && z->ch[0]==y){Rotate(x,0);Rotate(x,1);} else if(y->ch[0]==x && z->ch[0]==y){Rotate(y,1);Rotate(x,1);} else {Rotate(x,1);Rotate(x,0);} } } } void Access(Node *x){ for(Node *y=Null;x!=Null;y=x,x=x->fa){Splay(x);x->ch[1]=y;x->Pushup();} } void Makeroot(Node *x){ Access(x); Splay(x); x->rev^=1; } void Link(Node *x,Node *y){ Makeroot(x); x->fa=y; } void Cut(Node *x,Node *y){ Makeroot(x); Access(y); Splay(y); if(y->ch[0]==x){y->ch[0]=Null;x->fa=Null;} } Node *Find(Node *x){ Access(x); Splay(x); while(x->ch[0]!=Null)x=x->ch[0]; return x; } Node *ToLct(int x){ return root[x]; } int Xor(int x,int y){ Node *u=ToLct(x),*v=ToLct(y); Makeroot(u); Access(v); Splay(v); return v->ans; } void Add(int x,int y){ Node *u=ToLct(x),*v=ToLct(y); Link(u,v); } void Delete(int x,int y){ Node *u=ToLct(x),*v=ToLct(y); Cut(u,v); } void Change(int x,int y){ Node *u=ToLct(x); Access(u); Splay(u); u->v=y; u->Pushup(); } Node *GetNull(){ Node *re=new Node(0,re); re->v=re->ans=re->rev=0; re->ch[0]=re->fa=re->ch[1]=re; return re; } int main(){ freopen("3282.in","r",stdin); freopen("3282.out","w",stdout); scanf("%d %d",&n,&m); Null=GetNull(); for(int i=1;i<=n;i++){ int tp; scanf("%d",&tp); root[i]=new Node(tp,Null); } for(int i=1;i<=m;i++){ int opt,x,y; scanf("%d %d %d",&opt,&x,&y); if(opt==0){printf("%d\n",Xor(x,y));} if(opt==1 && Find(ToLct(x))!=Find(ToLct(y)) && x!=y){Add(x,y);} if(opt==2 && Find(ToLct(x))==Find(ToLct(y)) && x!=y){Delete(x,y);} if(opt==3){Change(x,y);} } return 0; }
疯狂的块状链表……
我写个半成品程序放这儿坑着……不知道哪天会填坑……
感觉写到快崩溃了……
jcvb写的完整版也就我这么长……但我只写了一半……orzorz
#include<cstdio> #include<cmath> #include<algorithm> using namespace std; struct List{ long long cur[1105],cover,rev,tag,sum,mx,mn,siz; List *prev,*next; List(List *pre,List *nex){ siz=0; mx=-21000000000ll; mn=21000000000ll; sum=0; rev=0; tag=0; cover=-21000000000ll; prev=pre; next=nex; } void Renew(long long k){ mx=max(mx,k); mn=min(mn,k); sum+=k; } void Fix(){ prev->next=this; next->prev=this; } }*root,*Null=new List(Null,Null); int m,n,block_size; long long a[100005],tmp[1105]; void Read(long long &x){ char ch; while((ch=getchar())<'0' || ch>'9'); x=ch-'0'; while((ch=getchar())>='0' && ch<='9')x=x*10+ch-'0'; } void Read(int &x){ char ch; while((ch=getchar())<'0' || ch>'9'); x=ch-'0'; while((ch=getchar())>='0' && ch<='9')x=x*10+ch-'0'; } void PushTag(List *p){ if(p->tag){ for(int i=0;i<p->siz;i++)p->cur[i]+=p->tag; p->tag=0; } } void PushCover(List *p){ if(p->cover!=-21000000000ll){ for(int i=0;i<p->siz;i++)p->cur[i]=p->cover; p->cover=-21000000000ll; } } void PushRev(List *p){ if(p->rev){ for(int i=0;i<p->siz/2;i++)swap(p->cur[i],p->cur[p->siz-i-1]); p->rev=0; } } void Pushdown(List *p){ PushTag(p); PushCover(p); PushRev(p); } void CopyTags(List *p,List *q){ p->cover=q->cover; p->tag=q->tag; p->rev=q->rev; } List* Split(List *lis,int k){ List *p=new List(lis,lis->next); lis->next=p; lis->Fix(); p->Fix(); PushRev(lis); CopyTags(p,lis); lis->mx=-21000000000ll; lis->mn=21000000000ll; lis->sum=0; for(int i=0;i<=k;i++){ lis->Renew(lis->cur[i]); } lis->siz=k+1; if(p->cover)return p; for(int i=k+1;i<lis->siz;i++){ p->cur[p->siz++]=lis->cur[i]; p->Renew(lis->cur[i]); } return p; } List* Merge(List *p,List *q){ p->next=q; q->prev=p; p->Fix(); q->Fix(); Pushdown(p); Pushdown(q); for(int i=0;i<q->siz;i++){ p->cur[p->siz++]=q->cur[i]; p->Renew(q->cur[i]); } return p; } void Swap(List *p,List *q){ p->prev->next=q; q->next->prev=p; p->next->prev=q; q->prev->next=p; swap(p->next,q->next); swap(p->prev,q->prev); } pair<List*,int> Location(int pos){ List *i; for(i=root;i!=Null && pos>i->siz;pos-=i->siz,i=i->next); return make_pair(i,pos-1); } ///Wo Mei You You Hua block_size; void Insert(int pos,long long val){ pair<List*,int> Real=Location(pos); Real.second++; Pushdown(Real.first); for(int i=Real.first->siz;i>Real.second;i--){ Real.first->cur[i]=Real.first->cur[i-1]; } Real.first->siz++; Real.first->cur[Real.second]=val; Real.first->Renew(val); if(Real.first->siz>2*block_size){Split(Real.first,Real.first->siz/2);} } void Delete(int pos){ pair<List*,int> Real=Location(pos); Pushdown(Real.first); Real.first->mx=-2100000000ll; Real.first->mn=21000000000ll; Real.first->sum=0; for(int i=0;i<Real.second;i++)Real.first->Renew(Real.first->cur[i]); for(int i=Real.second+1;i<Real.first->siz;i++){ Real.first->Renew(Real.first->cur[i]); Real.first->cur[i-1]=Real.first->cur[i]; } Real.first->siz--; if(Real.first->siz<block_size/2){ if(Real.first->next!=Null){Merge(Real.first,Real.first->next);} else { if(Real.first->prev!=Null){Merge(Real.first->prev,Real.first);} } } } void Reverse(int l,int r){ pair<List*,int> R1=Location(l),R2=Location(r); Pushdown(R1.first); Pushdown(R2.first); List *p=Split(R1.first,R1.second),*q=Split(R2.first,R2.second)->prev; int flag=0; for(List *i=p;i!=q;i=i->next){i->rev^=1;} for(;p!=q && p!=q->next;p=p->next,q=q->prev)Swap(p,q); } void True_rotate(List *lis,int k){ int cnt=0,Circle=lis->siz; for(int i=0;i<Circle;i++){ tmp[(++cnt+k-1)%Circle+1]=lis->cur[i]; } for(int i=0;i<Circle;i++){ lis->cur[i]=tmp[i-k+1]; } } void Rotate(int l,int r,int k){ pair<List*,int> R1=Location(l),R2=Location(r); if(R1.first==R2.first){ List *p=Split(R1.first,R1.second-1),*q=Split(R1.first->next,R2.second-R1.second+1)->prev; p=Merge(p,q); True_rotate(p,k); return; } if(R1.first->next==R2.first){ List *p=Split(R1.first,R1.second-1),*q=Split(R2.first,R2.second)->prev; p=Merge(p,q); True_rotate(p,k); return; } } void Add(int l,int r,long long v){ } void Cover(int l,int r,long long val){ } long long Sum(int l,int r){} long long MinAbs(int l,int r){} long long PrevNext(int l,int r,long long val){} long long Kth(int l,int r,int k){} int Rank(int l,int r,long long val){} int main(){ freopen("3337.in","r",stdin); freopen("3337.out","w",stdout); Read(n); for(int i=1;i<=n;i++){ Read(a[i]); } block_size=(int)sqrt((double)n); root=new List(Null,Null); List *p=root; int Count=0; for(int i=1;i<=n;i++){ if((i-1)%block_size==0 && i!=1){ p->next=new List(p,Null); p->siz=Count; p=p->next; Count=0; } p->Renew(a[i]); p->cur[Count++]=a[i]; } p->siz=Count; Read(m); while(m--){ int opt,l,r,k; long long v; Read(opt); if(opt==1){ Read(k);Read(v); Insert(k,v); } if(opt==2){ Read(k); Delete(k); } if(opt==3){ Read(l);Read(r); Reverse(l,r); } if(opt==4){ Read(l);Read(r);Read(k); Rotate(l,r,k); } if(opt==5){ Read(l);Read(r);Read(v); Add(l,r,v); } if(opt==6){ Read(l);Read(r);Read(v); Cover(l,r,v); } if(opt==7){ Read(l);Read(r); printf("%lld\n",Sum(l,r)); } if(opt==8){ Read(l);Read(r); printf("%lld\n",MinAbs(l,r)); } if(opt==9){ Read(l);Read(r);Read(v); printf("%lld\n",PrevNext(l,r,v)); } if(opt==10){ Read(l);Read(r);Read(k); printf("%lld\n",Kth(l,r,k)); } if(opt==11){ Read(l);Read(r);Read(v); printf("%d\n",Rank(l,r,v)); } } return 0; }
Splay模版题。
虽然最近学习了fhqTreap但是还是先写个splay吧,补一补以前的漏洞……
Splay
#include<cstdio> #include<algorithm> using namespace std; struct Node{ Node *ch[2],*fa; int v,mx,tag,rev,siz; Node(int val,Node* fa); void Pushup(); void Pushdown(); }*root,*Null=new Node(-2100000000,Null); int n,m; Node::Node(int val=0,Node* fat=Null){ siz=1; fa=fat; ch[0]=ch[1]=Null; v=mx=val; tag=0; } void Node::Pushdown(){ if(rev){ if(ch[0]!=Null)ch[0]->rev^=1; if(ch[1]!=Null)ch[1]->rev^=1; swap(ch[0],ch[1]); rev=0; } if(tag){ if(ch[0]!=Null){ch[0]->tag+=tag;ch[0]->v+=tag;ch[0]->mx+=tag;} if(ch[1]!=Null){ch[1]->tag+=tag;ch[1]->v+=tag;ch[1]->mx+=tag;} tag=0; } } void Node::Pushup(){ siz=1; if(ch[0]!=Null)siz+=ch[0]->siz; if(ch[1]!=Null)siz+=ch[1]->siz; mx=v; if(ch[0]!=Null)mx=max(mx,ch[0]->mx); if(ch[1]!=Null)mx=max(mx,ch[1]->mx); } 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[1]==x && z->ch[1]==y){Rotate(y,0);Rotate(x,0);} else if(y->ch[1]==x && z->ch[0]==y){Rotate(x,0);Rotate(x,1);} else if(y->ch[0]==x && z->ch[0]==y){Rotate(y,1);Rotate(x,1);} else {Rotate(x,1);Rotate(x,0);} } } if(place==Null)root=x; } Node* Build_Tree(int l,int r){ int mid=l+r>>1; if(l>r)return Null; Node *splay=new Node(0,Null); splay->ch[0]=Build_Tree(l,mid-1); if(splay->ch[0]!=Null){splay->ch[0]->fa=splay;} splay->ch[1]=Build_Tree(mid+1,r); if(splay->ch[1]!=Null){splay->ch[1]->fa=splay;} splay->Pushup(); return splay; } void Build(){ Null->siz=0; root=new Node(-2100000000,Null); root->ch[1]=new Node(-2100000000,root); root->ch[1]->fa=root; root->ch[1]->ch[0]=Build_Tree(1,n); root->ch[1]->ch[0]->fa=root->ch[1]; root->ch[1]->Pushup(); root->Pushup(); } Node *Find(Node *splay,int k){ if(splay->rev || splay->tag)splay->Pushdown(); if(k==splay->ch[0]->siz+1){return splay;} if(k<=splay->ch[0]->siz){return Find(splay->ch[0],k);} else {return Find(splay->ch[1],k-1-splay->ch[0]->siz);} } Node *GetSeq(int l,int r){ Node *L=Find(root,l); Splay(L,Null); Node *R=Find(root,r+2); Splay(R,root); return R->ch[0]; } void Reverse(int l,int r){ Node *seq=GetSeq(l,r); seq->rev^=1; } void Add(int l,int r,int val){ Node *seq=GetSeq(l,r); seq->tag+=val; seq->v+=val; seq->mx+=val; } int GetMx(int l,int r){ Node *seq=GetSeq(l,r); return seq->mx; } int main(){ freopen("1251.in","r",stdin); freopen("1251.out","w",stdout); scanf("%d %d",&n,&m); Build(); while(m--){ int opt,l,r,v; scanf("%d",&opt); if(opt==1){scanf("%d %d %d",&l,&r,&v);Add(l,r,v);} if(opt==2){scanf("%d %d",&l,&r);Reverse(l,r);} if(opt==3){scanf("%d %d",&l,&r);printf("%d\n",GetMx(l,r));} } return 0; }
fhqTreap(待填坑)
Host by is-Programmer.com | Power by Chito 1.3.3 beta | Theme: Aeros 2.0 by TheBuckmaker.com