BZOJ3589动态树

**错误改了一上午。

先做熟练泼粪

k<=5,因此我们可以模拟这个过程,在线段树上把标记建出来然后pushup时候更新就好了。

By:大奕哥

  1 #include<bits/stdc++.h>
  2 using namespace std;
  3 const int N=200005;
  4 struct tree{
  5     int l,lz,ll;long long s,ret;
  6 }t[N<<2];
  7 int head[N],cnt,n,id,bel[N],pos[N],size[N],d[N],f[N],son[N],ed[N];
  8 struct node{
  9     int to,nex;
 10 }e[N<<1];
 11 void add(int x,int y)
 12 {
 13     e[++cnt].to=y;e[cnt].nex=head[x];head[x]=cnt;
 14 }
 15 void dfs(int x)
 16 {
 17     size[x]=1;
 18     for(int i=head[x];i;i=e[i].nex)
 19     {
 20         int y=e[i].to;
 21         if(y==f[x])continue;
 22         d[y]=d[x]+1;f[y]=x;
 23         dfs(y);
 24         if(size[y]>size[son[x]])son[x]=y;
 25         size[x]+=size[y];
 26     }
 27     return;
 28 }
 29 void dfs2(int x,int chain)
 30 {
 31     pos[x]=++id;bel[x]=chain;
 32     if(son[x])dfs2(son[x],chain);
 33     for(int i=head[x];i;i=e[i].nex)
 34     {
 35         int y=e[i].to;
 36         if(y==f[x]||y==son[x])continue;
 37         dfs2(y,y);
 38     }
 39     ed[x]=id;
 40     return;
 41 }
 42 void update(int x,int z)
 43 {
 44     t[x].lz+=z;
 45     t[x].s+=z*t[x].l;
 46 }
 47 void update2(int x,int z)
 48 {
 49     t[x].ll=z;
 50     t[x].ret=t[x].s*z;
 51 }
 52 void pushdown(int x)
 53 {
 54     if(t[x].lz)
 55     {
 56         update(x<<1,t[x].lz);
 57         update(x<<1|1,t[x].lz);
 58         t[x].lz=0;
 59     }
 60     if(t[x].ll!=-1)
 61     {
 62         update2(x<<1,t[x].ll);
 63         update2(x<<1|1,t[x].ll);
 64         t[x].ll=-1;
 65     }
 66     return;
 67 }
 68 void pushup(int x)
 69 {
 70     t[x].s=t[x<<1].s+t[x<<1|1].s;
 71     t[x].ret=t[x<<1].ret+t[x<<1|1].ret;
 72 }
 73 void build(int x,int l,int r)
 74 {
 75     t[x].ll=-1;
 76     if(l==r){
 77         t[x].l=1;return;
 78     }
 79     int mid=l+r>>1;
 80     t[x].l=r-l+1;
 81     build(x<<1,l,mid);build(x<<1|1,mid+1,r);
 82 }
 83 void paint(int x,int l,int r,int L,int R,int w)
 84 {
 85     if(t[x].ll==w)return;
 86     if(l==L&&r==R){
 87         update2(x,w);
 88         return;
 89     }
 90     pushdown(x);
 91     int mid=l+r>>1;
 92     if(mid<L)paint(x<<1|1,mid+1,r,L,R,w);
 93     else if(mid>=R)paint(x<<1,l,mid,L,R,w);
 94     else paint(x<<1,l,mid,L,mid,w),paint(x<<1|1,mid+1,r,mid+1,R,w);
 95     pushup(x);
 96     return;
 97 }
 98 void change(int x,int l,int r,int L,int R,int c)
 99 {
100     if(l==L&&r==R)
101     {
102         update(x,c);
103         return;
104     }
105     pushdown(x);
106     int mid=l+r>>1;
107     if(mid<L)change(x<<1|1,mid+1,r,L,R,c);
108     else if(mid>=R)change(x<<1,l,mid,L,R,c);
109     else change(x<<1,l,mid,L,mid,c),change(x<<1|1,mid+1,r,mid+1,R,c);
110     pushup(x);
111 }
112 void color(int x,int y,int c)
113 {
114     while(bel[x]!=bel[y])
115     {
116         if(d[bel[x]]<d[bel[y]])swap(x,y);
117         paint(1,1,n,pos[bel[x]],pos[x],c);
118         x=f[bel[x]];
119     }
120     if(d[x]<d[y])swap(x,y);
121     paint(1,1,n,pos[y],pos[x],c);
122     return;
123 }
124 int main()
125 {
126     int x,y,q,ff,k;
127     scanf("%d",&n);
128     for(int i=1;i<n;++i)
129     {
130         scanf("%d%d",&x,&y);
131         add(x,y);add(y,x);
132     }
133     dfs(1);dfs2(1,1);
134     build(1,1,n);
135     scanf("%d",&q);
136     for(int i=1;i<=q;++i)
137     {
138         scanf("%d",&ff);
139         if(ff==0)
140         {
141             scanf("%d%d",&x,&y);
142             change(1,1,n,pos[x],ed[x],y);
143         }
144         else{
145             scanf("%d",&k);
146             for(int j=1;j<=k;++j)
147             {
148                 scanf("%d%d",&x,&y);
149                 color(x,y,1);
150             }
151             printf("%d\n",t[1].ret&((1ll<<31)-1));
152             update2(1,0);
153         }
154     }
155     return 0;
156 }

 

posted @ 2018-02-11 11:50  大奕哥&VANE  阅读(226)  评论(0编辑  收藏  举报