BZOJ4372: 烁烁的游戏(动态点分治)

Description

背景:烁烁很喜欢爬树,这吓坏了树上的皮皮鼠。
题意:
给定一颗n个节点的树,边权均为1,初始树上没有皮皮鼠。
烁烁他每次会跳到一个节点u,把周围与他距离不超过d的节点各吸引出w只皮皮鼠。皮皮鼠会被烁烁吸引,所以会一直待在节点上不动。
烁烁很好奇,在当前时刻,节点u有多少个他的好朋友---皮皮鼠。
大意:
给一颗n个节点的树,边权均为1,初始点权均为0,m次操作:
Q x:询问x的点权。
M x d w:将树上与节点x距离不超过d的节点的点权均加上w。

Input

第一行两个正整数:n,m
接下来的n-1行,每行三个正整数u,v,代表u,v之间有一条边。
接下来的m行,每行给出上述两种操作中的一种。

Output

对于每个Q操作,输出当前x节点的皮皮鼠数量。

Sample Input

7 6
1 2
1 4
1 5
2 3
2 7
5 6
M 1 1 2
Q 5
M 2 2 3
Q 3
M 1 2 1
Q 2

Sample Output

2
3
6

解题思路:

和震波很像,查询修改反过来就好了。

代码:

  1 #include<cstdio>
  2 #include<cstring>
  3 #include<algorithm>
  4 const int N=100010;
  5 struct pnt{
  6     int hd;
  7     int fa;
  8     int f;
  9     int tp;
 10     int wgt;
 11     int mxs;
 12     int dis;
 13     bool vis;
 14     int roota;
 15     int rootp;
 16 }p[N];
 17 struct trnt{
 18     int ls;
 19     int rs;
 20     int val;
 21 }tr[40000000];
 22 struct ent{
 23     int twd;
 24     int lst;
 25 }e[N<<1];
 26 int n,m;
 27 int cnt;
 28 int siz;
 29 int root;
 30 int size;
 31 int maxsize;
 32 char cmd[1000];
 33 void ade(int f,int t)
 34 {
 35     cnt++;
 36     e[cnt].twd=t;
 37     e[cnt].lst=p[f].hd;
 38     p[f].hd=cnt;
 39     return ;
 40 }
 41 void Basic_dfs(int x,int f)
 42 {
 43     p[x].dis=p[f].dis+1;
 44     p[x].f=f;
 45     p[x].wgt=1;
 46     int maxs=-1;
 47     for(int i=p[x].hd;i;i=e[i].lst)
 48     {
 49         int to=e[i].twd;
 50         if(to==f)
 51             continue;
 52         Basic_dfs(to,x);
 53         p[x].wgt+=p[to].wgt;
 54         if(maxs<p[to].wgt)
 55         {
 56             maxs=p[to].wgt;
 57             p[x].mxs=to;
 58         }
 59     }
 60     return ;
 61 }
 62 void Build_dfs(int x,int top)
 63 {
 64     if(!x)
 65         return ;
 66     p[x].tp=top;
 67     Build_dfs(p[x].mxs,top);
 68     for(int i=p[x].hd;i;i=e[i].lst)
 69     {
 70         int to=e[i].twd;
 71         if(to==p[x].mxs||to==p[x].f)
 72             continue;
 73         Build_dfs(to,to);
 74     }
 75     return ;
 76 }
 77 int Lca(int x,int y)
 78 {
 79     while(p[x].tp!=p[y].tp)
 80     {
 81         if(p[p[x].tp].dis<p[p[y].tp].dis)
 82             std::swap(x,y);
 83         x=p[p[x].tp].f;
 84     }
 85     if(p[x].dis>p[y].dis)
 86         std::swap(x,y);
 87     return x;
 88 }
 89 int Dis(int x,int y)
 90 {
 91     int z=Lca(x,y);
 92     return p[x].dis+p[y].dis-2*p[z].dis;
 93 }
 94 void grc_dfs(int x,int f)
 95 {
 96     p[x].wgt=1;
 97     int maxs=-1;
 98     for(int i=p[x].hd;i;i=e[i].lst)
 99     {
100         int to=e[i].twd;
101         if(to==f||p[to].vis)
102             continue;
103         grc_dfs(to,x);
104         p[x].wgt+=p[to].wgt;
105         if(maxs<p[to].wgt)
106             maxs=p[to].wgt;
107     }
108     maxs=std::max(maxs,size-p[x].wgt);
109     if(maxs<maxsize)
110     {
111         root=x;
112         maxsize=maxs;
113     }
114     return ;
115 }
116 void bin_dfs(int x,int f)
117 {
118     p[x].fa=f;
119     p[x].vis=true;
120     int tmp=size;
121     for(int i=p[x].hd;i;i=e[i].lst)
122     {
123         int to=e[i].twd;
124         if(p[to].vis)
125             continue;
126         root=0;
127         if(p[x].wgt>p[to].wgt)
128             size=p[to].wgt;
129         else
130             size=tmp-p[x].wgt;
131         maxsize=0x3f3f3f3f;
132         grc_dfs(to,to);
133         bin_dfs(root,x);
134     }
135     return ;
136 }
137 void update(int &spc,int l,int r,int ll,int rr,int v)
138 {
139     if(ll>r||l>rr)
140         return ;
141     if(!spc)
142         spc=++siz;
143     if(ll<=l&&r<=rr)
144     {
145         tr[spc].val+=v;
146         return ;
147     }
148     int mid=(l+r)>>1;
149     update(tr[spc].ls,l,mid,ll,rr,v);
150     update(tr[spc].rs,mid+1,r,ll,rr,v);
151     return ;
152 }
153 int query(int spc,int l,int r,int pos)
154 {
155     if(!spc)
156         return 0;
157     int ans=tr[spc].val;
158     if(l==r)
159         return ans;
160     int mid=(l+r)>>1;
161     if(pos<=mid)
162         ans+=query(tr[spc].ls,l,mid,pos);
163     else
164         ans+=query(tr[spc].rs,mid+1,r,pos);
165     return ans;
166 }
167 void Update(int x,int k,int val)
168 {
169     update(p[x].rootp,0,n-1,0,k,val);
170     for(int i=x;p[i].fa;i=p[i].fa)
171     {
172         int d=Dis(x,p[i].fa);
173         if(k<d)
174             continue;
175         update(p[p[i].fa].rootp,0,n-1,0,k-d,val);
176         update(p[i].roota,0,n-1,0,k-d,val);
177     }
178     return ;
179 }
180 int Query(int x)
181 {
182     int ans=query(p[x].rootp,0,n-1,0);
183     for(int i=x;p[i].fa;i=p[i].fa)
184     {
185         int d=Dis(x,p[i].fa);
186         ans+=query(p[p[i].fa].rootp,0,n-1,d)-query(p[i].roota,0,n-1,d);
187     }
188     return ans;
189 }
190 int main()
191 {
192     scanf("%d%d",&n,&m);
193     for(int i=1;i<n;i++)
194     {
195         int a,b;
196         scanf("%d%d",&a,&b);
197         ade(a,b);
198         ade(b,a);
199     }
200     Basic_dfs(1,1);
201     Build_dfs(1,1);
202     root=0;
203     size=n;
204     maxsize=0x3f3f3f3f;
205     grc_dfs(1,1);
206     bin_dfs(root,0);
207     while(m--)
208     {
209         scanf("%s",cmd+1);
210         if(cmd[1]=='M')
211         {
212             int x,k,v;
213             scanf("%d%d%d",&x,&k,&v);
214             Update(x,k,v);
215         }else{
216             int x;
217             scanf("%d",&x);
218             printf("%d\n",Query(x));
219         }
220     }
221     return 0;
222 }

 

posted @ 2018-12-22 09:47  Unstoppable728  阅读(265)  评论(0编辑  收藏  举报