BZOJ 3323 splay维护序列

来源:互联网 发布:删除表某一行的sql语句 编辑:程序博客网 时间:2024/05/21 06:27

就第三个操作比较新颖
转化成 在l前插一个点
把r和r+1合并

//By SiriusRen#include <cstdio>#include <cstring>#include <algorithm>using namespace std;const int maxn=100005,mod=20130426;typedef long long ll;struct Tree{    int fa,ch[2];ll add,mul,size,val;}tr[666666];int cnt,root,n,xx,yy,zz;ll ans,t,al;char op[10];void push_up(int x){    int lson=tr[x].ch[0],rson=tr[x].ch[1];    tr[x].size=tr[lson].size+tr[rson].size+1;}void push_down(int x){    if(!x||(tr[x].mul==1&&tr[x].add==0))return;    int lson=tr[x].ch[0],rson=tr[x].ch[1];    ((tr[lson].add*=tr[x].mul)+=tr[x].add)%=mod;    ((tr[rson].add*=tr[x].mul)+=tr[x].add)%=mod;    ((tr[lson].val*=tr[x].mul)+=tr[x].add)%=mod;    ((tr[rson].val*=tr[x].mul)+=tr[x].add)%=mod;    (tr[lson].mul*=tr[x].mul)%=mod;    (tr[rson].mul*=tr[x].mul)%=mod;    tr[x].mul=1,tr[x].add=0;}int build(int l,int r,int father){    if(l>r)return 0;    int pos=++cnt;    tr[pos].size=1,tr[pos].fa=father,tr[pos].mul=1;    if(l==r)return pos;    int mid=(l+r)>>1;    tr[pos].ch[0]=build(l,mid-1,pos);    tr[pos].ch[1]=build(mid+1,r,pos);    push_up(pos);    return pos;}void rotate(int p){    int q=tr[p].fa,y=tr[q].fa,x=(tr[q].ch[1]==p);    tr[q].ch[x]=tr[p].ch[!x];tr[tr[q].ch[x]].fa=q;    tr[p].ch[!x]=q;tr[q].fa=p;tr[p].fa=y;    if(y)tr[y].ch[tr[y].ch[1]==q]=p;    push_up(q);}void splay(int x,int tp){    for(int y;y=tr[x].fa;rotate(x)){        if(y==tp)break;        if(tr[y].fa!=tp){            if((tr[y].ch[0]==x)^(tr[tr[y].fa].ch[0]==y))rotate(x);            else rotate(y);        }    }push_up(x);    if(!tp)root=x;}void dfs(int x){    if(!x)return;    push_down(x);    dfs(tr[x].ch[0]);    if(++al>0)(ans+=t*tr[x].val)%=mod,(t*=xx)%=mod;    dfs(tr[x].ch[1]);}int find(int x,int sz){    push_down(x);    if(tr[tr[x].ch[0]].size+1==sz)return x;    else if(tr[tr[x].ch[0]].size>=sz)return find(tr[x].ch[0],sz);    else return find(tr[x].ch[1],sz-tr[tr[x].ch[0]].size-1);}int main(){    scanf("%d",&n);    root=build(0,maxn,0);    while(n--){        scanf("%s",op);        if(op[0]=='a'){            scanf("%d%d%d",&xx,&yy,&zz);            int fx=find(root,xx+1),fy=find(root,yy+3);            splay(fx,0),splay(fy,fx);            (tr[tr[fy].ch[0]].add+=zz)%=mod,(tr[tr[fy].ch[0]].val+=zz)%=mod;            push_up(fy),push_up(fx);        }        else if(op[3]=='x'){            scanf("%d%d",&xx,&yy);            int fx=find(root,yy+1),fy=find(root,yy+4);            splay(fx,0),splay(fy,fx);            push_down(fx),push_down(fy),push_down(tr[fy].ch[0]);            int now1=tr[fy].ch[0],now2=tr[now1].ch[0]+tr[now1].ch[1];            tr[now1].val+=tr[now2].val,tr[now1].size=1;            tr[now2].fa=tr[now1].ch[0]=tr[now1].ch[1]=0;            push_up(fy),push_up(fx);            fx=find(root,xx+1),fy=find(root,xx+2);            splay(fx,0),splay(fy,fx);tr[fy].ch[0]=++cnt;            tr[cnt].size=1,tr[cnt].fa=fy,tr[cnt].mul=1;            push_up(fy),push_up(fx);        }        else if(op[0]=='q'){            scanf("%d",&xx),ans=0,t=1,al=-1,dfs(root),printf("%lld\n",ans);        }        else{            scanf("%d%d%d",&xx,&yy,&zz);            int fx=find(root,xx+1),fy=find(root,yy+3);            splay(fx,0),splay(fy,fx);            (tr[tr[fy].ch[0]].mul*=zz)%=mod,(tr[tr[fy].ch[0]].val*=zz)%=mod;            (tr[tr[fy].ch[0]].add*=zz)%=mod,push_up(fy),push_up(fx);         }    }}

这里写图片描述

0 0