bzoj2333: [SCOI2011]棘手的操作 线段树+离线

来源:互联网 发布:手机淘宝更改会员名 编辑:程序博客网 时间:2024/06/09 19:16

网上都是可并堆在线搞,其实直接离线处理处每个联通块,然后把他们放一起,然后点更新,区间询问就可以了。

#include <iostream>#include <algorithm>#include <cstring>#include <cstdio>using namespace std;#define INF 100000000#define lson l,mid,rt<<1#define rson mid+1,r,rt<<1|1#define getmid int mid=(l+r)>>1#define maxn 1200000int tree[maxn],add[maxn];int n,m,a[maxn],save[maxn];int next[maxn],id,w[maxn],ed[maxn],fa[maxn];struct Q{    int o,x,y;    void scan()    {        char s[3];        scanf("%s",s);        if(*s=='U')            scanf("%d %d",&x,&y),o=1;        else if(*s=='A'&&s[1]=='1')            scanf("%d %d",&x,&y),o=2;        else if(*s=='A'&&s[1]=='2')            scanf("%d %d",&x,&y),o=3;        else if(*s=='A'&&s[1]=='3')            scanf("%d",&x),o=4;        else if(*s=='F'&&s[1]=='1')            scanf("%d",&x),o=5;        else if(*s=='F'&&s[1]=='2')            scanf("%d",&x),o=6;        else if(*s=='F'&&s[1]=='3')            o=7;    }}q[300020];void pushup(int rt){    tree[rt]=max(tree[rt<<1],tree[rt<<1|1]);}void pushdown(int rt){     if(add[rt])    {        add[rt<<1]+=add[rt];        add[rt<<1|1]+=add[rt];        tree[rt<<1]+=add[rt];        tree[rt<<1|1]+=add[rt];        add[rt]=0;    }}void update(int l,int r,int rt,int x,int y,int v){    if(x<=l&&r<=y)    {        add[rt]+=v;        tree[rt]+=v;        return;    }    pushdown(rt);    getmid;    if(x<=mid) update(lson,x,y,v);    if(y>mid) update(rson,x,y,v);    pushup(rt);}int qmax(int l,int r,int rt,int x,int y){    if(x<=l&&r<=y)    {        return tree[rt];    }    pushdown(rt);    getmid;    int ans=-INF;    if(x<=mid) ans=max(ans,qmax(lson,x,y));    if(y>mid) ans=max(ans,qmax(rson,x,y));    return ans;}void build(int l,int r,int rt){    if(l==r)    {        tree[rt]=save[l];        return;    }    getmid;    build(lson);    build(rson);    pushup(rt);}int getf(int x){    return fa[x]==x?x:fa[x]=getf(fa[x]);}int main(){    scanf("%d",&n);    for(int i=1;i<=n;i++)        scanf("%d",&a[i]);    for(int i=1;i<=n;i++)        fa[i]=i,ed[i]=i;    scanf("%d",&m);    int r1,r2;    for(int i=1;i<=m;i++)    {        q[i].scan();        if(q[i].o==1)        {            r1=getf(q[i].x);r2=getf(q[i].y);            if(r1==r2) continue;            fa[r2]=r1;            next[ed[r1]]=r2;            ed[r1]=ed[r2];        }    }    for(int i=1;i<=n;i++)    {        if(getf(i)==i)        {            for(int j=i;j;j=next[j])            {                id++;w[j]=id;save[id]=a[j];            }        }    }    build(1,n,1);    /*    for(int i=1;i<=n;i++)    {        printf("%d ",save[i]);        printf("%d\n",qmax(1,n,1,w[i],w[i]));    }    */    for(int i=1;i<=n;i++)    {        fa[i]=i;ed[i]=i;    }    for(int i=1;i<=m;i++)    {        if(q[i].o==1)        {            r1=getf(q[i].x);r2=getf(q[i].y);            if(r1==r2)                continue;            fa[r2]=r1;             ed[r1]=ed[r2] ;        }        else if(q[i].o==2)            update(1,n,1,w[q[i].x],w[q[i].x],q[i].y);        else if(q[i].o==3)            update(1,n,1,w[getf(q[i].x)],w[ed[getf(q[i].x)]],q[i].y);        else if(q[i].o==4)            update(1,n,1,1,n,q[i].x);        else if(q[i].o==5)            printf("%d\n",qmax(1,n,1,w[q[i].x],w[q[i].x]));        else if(q[i].o==6)            printf("%d\n",qmax(1,n,1,w[getf(q[i].x)],w[ed[getf(q[i].x)]]));        else if(q[i].o==7)            printf("%d\n",qmax(1,n,1,1,n));    }    return 0;}


0 0
原创粉丝点击