Hdu 5221 Occupation

来源:互联网 发布:airdroid windows 编辑:程序博客网 时间:2024/06/05 09:16
算是一个简单的树剖+线段树(不过话说回来树剖也是经常和线段树一起(这个题应该叫做线段树在树上的简单应用(Orz


感觉自己的线段树(特别是区间更新这个地方)还是很不熟练
(观看下文需要一些简单的线段树知识,包括但不限于线段树的定义)


如果不考虑树上的部分的话,这个题要求我们维护一个区间,其中区间中的每一个点都有一个标记和一个value,刚开始的时候,标记都是false
1 将区间[L,R]上所有没有标记的点都标记上
2 将u这个点的标记取消掉
3 询问区间[1,n]上被标记的所有点的权值和


(显然这个题要用到lazy标记(这不是废话吗,线段树什么区间更新的题不用lazy标记的(╯‵□′)╯︵┻━┻


定义lazy[o]==1时表示这个节点的区间是全部被标记的,这个节点的val就是区间和(也就是他的子节点的状态我们都能知道,虽然子节点的val和lazy是不定的,但是会被这一次操作覆盖)我们不知道是不是全部被标记的时候,lazy[o]都为0
随手维护一下前缀和(sum)


操作1好像就变得很简单了
我们只要在当前的区间被标记的区间完全覆盖的时候,把当前的lazy变成1,val[o]=sum[r]-sum[l-1]


然后看操作2


单点更新还是很简单的嗯
唯一需要注意的是如果在更新的路上碰到lazy[o]==1的情况,把这个状态push下去
然后在更新完之后维护一下就好


3的话就是根节点的val了(因为我们每次update之后都维护到了根节点


线段树的部分还是很简单的


然而有眼尖的同学会问,这个题不是要标记一个子树吗QAQ,子树怎么做呀,树链剖分好像不能处理子树的情况啊QAQQQQ


咳咳,仔细回忆一下,是不是有一个神奇的性质(并不),一个子树的dfs序是连续的!


(⊙v⊙)


还有什么问题吗






-------------------------我是代码的分割线-------------------

#include<cstdio>#include<cstring>#include<vector>#include<algorithm>using namespace std;#pragma comment(linker, "/STACK:102400000,102400000")const int maxn = 112345;#define lson o<<1,l,m#define rson o<<1|1,m+1,r#define Mid int m = (l+r)>>1#define root 1,1,n#define Now int o,int l,int r#define LL long longint arr[maxn];int aar[maxn];LL sum[maxn];int lazy[maxn*4];LL val[maxn*4];void sinit(int n){    memset(lazy,0,sizeof(lazy));    memset(val,0,sizeof(val));    sum[0]=0;    for(int i=1;i<=n;i++){        sum[i]=sum[i-1]+arr[i];    }}void maintain(Now){    lazy[o]=1;    val[o]=sum[r]-sum[l-1];}void update(Now,int ul,int ur){    if(ul<=l && r<=ur){        maintain(o,l,r);        return;    }    Mid;    if(lazy[o]==1){        return;    }    if(ul<=m)        update(lson,ul,ur);    if(m+1<=ur)        update(rson,ul,ur);    val[o]=val[o<<1]+val[o<<1|1];}void update(Now,int pos){  //  printf("pos = %d\n",pos);    if(l==r){        lazy[o]=val[o]=0;        return;    }    Mid;    if(lazy[o]==1){        lazy[o]=0;        maintain(lson);        maintain(rson);    }    if(pos<=m)        update(lson,pos);    else        update(rson,pos);    val[o]=val[o<<1]+val[o<<1|1];}vector<int> edge[maxn];void init(int n){    for(int i=0;i<=n;i++)        edge[i].resize(0);}void Link(int st,int ed){    edge[st].push_back(ed);    edge[ed].push_back(st);}int fa[maxn],son[maxn],tid[maxn],siz[maxn],top[maxn],deep[maxn];int _cnt;void dffs(int st,int Fa,int Deep){    deep[st]=Deep,son[st]=-1,siz[st]=1,fa[st]=Fa;    for(auto & x:edge[st]){        if(x!=Fa){            dffs(x,st,Deep+1);            siz[st]+=siz[x];            if(son[st]==-1 || siz[son[st]]<siz[x])                son[st]=x;        }    }}void dfss(int st,int Top){    tid[st]=_cnt++,top[st]=Top;    if(son[st]!=-1)        dfss(son[st],Top);    for(auto & x:edge[st]){        if(x!=fa[st] && x!=son[st]){            dfss(x,x);        }    }}void tinit(){    _cnt=1;    dffs(1,0,1);    dfss(1,1);}void UPD(int x,int y,int n){    int tx = top[x],ty=top[y];    while(tx!=ty){        if(deep[tx] > deep[ty]){ // up  x            update(root,tid[tx],tid[x]);            x=fa[tx],tx=top[x];        }        else{            update(root,tid[ty],tid[y]);            y=fa[ty],ty=top[y];        } //   printf("x = %d y = %d\n",x,y);    }    if(deep[x]>deep[y]){        update(root,tid[y],tid[x]);    }    else{        update(root,tid[x],tid[y]);    }}void UPD(int x,int n){    int id = tid[x];    int size = siz[x];    update(root,id,id+size-1);}int main(){    int n,m;    int T;    scanf("%d",&T);    while(T-- && ~scanf("%d",&n)){        for(int i=1;i<=n;i++)            scanf("%d",&aar[i]);        int u,v;        init(n);        for(int i=1;i<n;i++){            scanf("%d %d",&u,&v);            Link(u,v);        }        tinit();        for(int i=1;i<=n;i++){            arr[tid[i]]=aar[i];        }//        for(int i=1;i<=n;i++)//            printf(i<n?"%d ":"%d\n",tid[i]);//        for(int i=1;i<=n;i++)//            printf(i<n?"%d ":"%d\n",top[i]);        sinit(n);        scanf("%d",&m);        int ord;        while(m--){            scanf("%d",&ord);            if(ord==1){                scanf("%d %d",&u,&v);                UPD(u,v,n);            }            else if(ord==2){                scanf("%d",&u);                update(root,tid[u]);            }            else{                scanf("%d",&u);                UPD(u,n);            }            printf("%lld\n",val[1]);        }    }    return 0;}/*1101 2 3 4 5 6 7 8 9 101 21 32 42 55 95 103 63 73 861 10 41 9 72 53 42 41 6 10155 5 5 5 51 21 31 41 5100863 11008621 101 210086*/



0 0
原创粉丝点击
热门问题 老师的惩罚 人脸识别 我在镇武司摸鱼那些年 重生之率土为王 我在大康的咸鱼生活 盘龙之生命进化 天生仙种 凡人之先天五行 春回大明朝 姑娘不必设防,我是瞎子 苹果5s电源键坏了怎么办 苹果6s手机触屏失灵怎么办 不能取电池的手机触屏不灵怎么办? 7p主板触摸ic坏了怎么办 小米六手机摔了一下屏幕失灵怎么办 魅蓝5s触屏失灵怎么办 苹果手机键盘字母顺序乱了怎么办 红米手机进水后屏幕失灵怎么办 苹果7plus主屏按键坏了怎么办 苹果六手机上的红色变成粉色怎么办 苹果手机出现闪屏和手感不灵怎么办 荣耀6plus后开不了机怎么办 苹果手机touch id密码忘了怎么办 苹果7摔出了一个裂缝怎么办 屏幕摔坏了下键盘失灵怎么办 苹果4s手机按健失灵怎么办 金立手机摔了一下黑屏了怎么办 苹果5s屏幕不亮了怎么办 苹果6s手机开不了机怎么办 苹果手机充电的地方坏了怎么办 手机丢了只有imei码该怎么办 在保修期的苹果被偷了怎么办 苹果手机在保修期之外坏了怎么办 把苹果售后给的备用机摔了怎么办 把售后给的备用机摔坏了怎么办 苹果4s屏幕玻璃碎了怎么办 苹果手机摔鼓起来了屏幕花了怎么办 苹果8卡屏幕划不动了怎么办 苹果x卡屏幕划不动了怎么办 苹果5s解锁密码忘了怎么办 苹果6s屏幕摔碎了怎么办 苹果手机掉在水里了怎么办 乐视手机掉水里没法触屏了怎么办 乐视电视有声音但是黑屏怎么办 苹果手机微信语音有回音怎么办 苹果4s死机了没反应了怎么办 苹果手表的显示平坏了怎么办 苹果5s屏幕翘起来了怎么办 苹果手机圆点卡住屏幕不能动怎么办 苹果5s卡屏怎么也不动应该怎么办 苹果5s手机触摸屏太灵敏怎么办