BZOJ3995:道路修建(线段树维护MST)

来源:互联网 发布:手机淘宝登录界面 编辑:程序博客网 时间:2024/06/07 16:12

传送门

题意:
给一张2×n的网格图,只有相邻的点连了边,支持询问区间的最小生成树,以及修改边权。

题解:线段树。
%%%PoPoQQQ : http://blog.csdn.net/popoqqq/article/details/45080183

#include<bits/stdc++.h>using namespace std;struct IO{    streambuf *ib,*ob;    inline void init(){        ios::sync_with_stdio(false);        cin.tie(NULL);cout.tie(NULL);        ib=cin.rdbuf();ob=cout.rdbuf();    }    inline int read(){        char ch=ib->sbumpc();int i=0,f=1;        while(!isdigit(ch)){if(ch=='-')f=-1;ch=ib->sbumpc();}        while(isdigit(ch)){i=(i+(i<<2)<<1)+ch-'0';ch=ib->sbumpc();}        return i*f;    }    inline void W(long long x){        static int buf[50];        if(!x){ob->sputc('0');ob->sputc('\n');return;}        if(x<0){ob->sputc('-');x=-x;}        while(x){buf[++buf[0]]=x%10;x/=10;}        while(buf[0])ob->sputc(buf[buf[0]--]+'0');        ob->sputc('\n');    }}io;const int Maxn=3e5+50;int n,m,v[3][Maxn];struct node{    node *lc,*rc;    int sum,posl,posr,cntline,mxl,mxr,mxall;    inline void upt(int pos,node *x,node *y){        int mx=max(v[1][pos],max(v[2][pos],max(x->mxr,y->mxl)));        mxall=max(x->mxall,max(y->mxall,max(v[1][pos],v[2][pos])));        cntline=x->cntline+y->cntline;        if(mx==x->mxr){            sum=x->sum+y->sum-x->mxr+v[1][pos]+v[2][pos];            posr=y->posr;mxr=y->mxr;            if(v[0][x->posr]==x->mxr){                cntline--;                if(x->cntline==1){                    posl=y->posl;                    mxl=max(x->mxall,max(y->mxl,max(v[1][pos],v[2][pos])));                }                else posl=x->posl,mxl=x->mxl;            }            else posl=x->posl,mxl=x->mxl;        }        else if(mx==y->mxl){            sum=x->sum+y->sum-y->mxl+v[1][pos]+v[2][pos];            posl=x->posl;mxl=x->mxl;            if(v[0][y->posl]==y->mxl){                cntline--;                if(y->cntline==1){                    posr=x->posr;                    mxr=max(y->mxall,max(x->mxr,max(v[1][pos],v[2][pos])));                }                else posr=y->posr,mxr=y->mxr;            }            else posr=y->posr,mxr=y->mxr;        }        else {            sum=x->sum+y->sum+(mx==v[1][pos]?v[2][pos]:v[1][pos]);            posl=x->posl;posr=y->posr;            mxl=x->mxl;mxr=y->mxr;        }    }}Pool[Maxn],*pool=Pool,*null=Pool;inline node* newnode(){    ++pool;pool->lc=pool->rc=null;    return pool;}struct SegmentTree{    node *rt,*que[Maxn];    int tail,rpos[Maxn];    SegmentTree():rt(null){}    inline void build(node *&now,int l,int r){        now=newnode();        if(l==r){            now->sum=now->mxl=now->mxr=v[0][l];            now->posl=now->posr=l;            now->cntline=1;            return;        }        int mid=(l+r)>>1;        build(now->lc,l,mid);        build(now->rc,mid+1,r);        now->upt(mid,now->lc,now->rc);    }    inline void findpos(node *now,int l,int r,int L,int R){        if(L<=l&&r<=R){que[++tail]=now;rpos[tail]=r;return;}        int mid=(l+r)>>1;        if(L<=mid)findpos(now->lc,l,mid,L,R);        if(R>mid)findpos(now->rc,mid+1,r,L,R);    }    inline int query(int L,int R){        tail=0;        findpos(rt,1,n,L,R);        if(tail==1)return que[tail]->sum;        node tmp;tmp.upt(rpos[1],que[1],que[2]);        for(int i=2;i<tail;i++){            node tmp2=tmp;            tmp.upt(rpos[i],&tmp2,que[i+1]);        }        return tmp.sum;    }    inline void modify(node *&now,int l,int r,int pos){        if(l==r){            now->sum=now->mxl=now->mxr=v[0][l];            now->posl=now->posr=l;            now->cntline=1;            return;        }        int mid=(l+r)>>1;        if(pos<=mid)modify(now->lc,l,mid,pos);        else modify(now->rc,mid+1,r,pos);        now->upt(mid,now->lc,now->rc);    }}ST;int main(){    io.init();n=io.read(),m=io.read();    for(int i=1;i<n;i++)v[1][i]=io.read();    for(int i=1;i<n;i++)v[2][i]=io.read();    for(int i=1;i<=n;i++)v[0][i]=io.read();    ST.build(ST.rt,1,n);    for(int i=1;i<=m;i++){        static char ch[2];        cin>>(ch+1);        if(ch[1]=='Q'){            int l=io.read(),r=io.read();            io.W(ST.query(l,r));        }        else{            int r1=io.read(),c1=io.read(),r2=io.read(),c2=io.read();            if(r1==r2){                if(c1>c2)swap(c1,c2);                v[r1][c1]=io.read();                ST.modify(ST.rt,1,n,c2);            }            else{                v[0][c1]=io.read();                ST.modify(ST.rt,1,n,c1);            }        }    }}
原创粉丝点击