# BZOJ 4372/3370 烁烁的游戏/震波 (动态点分治+线段树)

  1 #include <map>
2 #include <queue>
3 #include <vector>
4 #include <cstdio>
5 #include <cstring>
6 #include <algorithm>
7 #define N1 101000
8 #define ll long long
9 #define dd double
10 #define inf 0x3f3f3f3f3f3f3f3fll
11 using namespace std;
12
13 int gint()
14 {
15     int ret=0,fh=1;char c=getchar();
16     while(c<'0'||c>'9'){if(c=='-')fh=-1;c=getchar();}
17     while(c>='0'&&c<='9'){ret=ret*10+c-'0';c=getchar();}
18     return ret*fh;
19 }
20
21 struct SEG{
22 int sum[N1*150],ls[N1*150],rs[N1*150],rm[N1],rf[N1],tot;
23 void pushup(int rt){sum[rt]=sum[ls[rt]]+sum[rs[rt]];}
24 void update(int x,int l,int r,int &rt,int w)
25 {
26     if(!rt) rt=++tot;
27     if(l==r) {sum[rt]+=w;return;}
28     int mid=(l+r)>>1;
29     if(x<=mid) update(x,l,mid,ls[rt],w);
30     else update(x,mid+1,r,rs[rt],w);
31     pushup(rt);
32 }
33 int query(int L,int R,int l,int r,int rt)
34 {
35     if(!rt) return 0;
36     if(L<=l&&r<=R) return sum[rt];
37     int mid=(l+r)>>1,ans=0;
38     if(L<=mid) ans+=query(L,R,l,mid,ls[rt]);
39     if(R>mid) ans+=query(L,R,mid+1,r,rs[rt]);
40     return ans;
41 }
42 }s;
43
44 struct Edge{
46 void ae(int u,int v)
48 }e;
49
50 int n,m,T;
51 namespace tr{
52 int dep[N1],ff[N1<<1][20],st[N1],id[N1<<1],lg[N1<<1],tot;
54 {
55     id[++tot]=u; st[u]=tot; ff[tot][0]=u;
57     {
59         dep[v]=dep[u]+1; dfs1(v,u); id[++tot]=u; ff[tot][0]=u;
60     }
61 }
62 void get_st()
63 {
64     int i,j;
65     for(lg[1]=0,i=2;i<=tot;i++) lg[i]=lg[i>>1]+1;
66     for(j=1;j<=lg[tot];j++)
67         for(i=1;i+(1<<j)-1<=tot;i++)
68         ff[i][j]=dep[ ff[i][j-1] ]<dep[ ff[i+(1<<(j-1))][j-1] ]?ff[i][j-1]:ff[i+(1<<(j-1))][j-1];
69 }
70 int dis(int x,int y)
71 {
72     int tx=min(st[x],st[y]),ty=max(st[x],st[y]),L=ty-tx+1;
73     int fa=dep[ ff[tx][lg[L]] ]<dep[ ff[ty-(1<<lg[L])+1][lg[L]] ]?ff[tx][lg[L]]:ff[ty-(1<<lg[L])+1][lg[L]];
74     return dep[x]+dep[y]-2*dep[fa];
75 }
76 void init(){dfs1(1,-1);get_st();}
77 };
78
79 using tr::dis;
80
82 void dfs(int u,int dad,int g)
83 {
86     {
88         dep[v]=dep[u]+1; dfs(v,u,g); sz[u]+=sz[v];
89     }
90 }
92 {
93     sz[u]=1; ms[u]=0;
95     {
97         gra(v,u); sz[u]+=sz[v]; ms[u]=max(ms[u],sz[v]);
98     }
99     ms[u]=max(ms[u],tsz-sz[u]);
100     if(ms[u]<ms[G]) G=u;
101 }
102 void main_dfs(int u)
103 {
104     use[u]=1; dep[u]=0; dfs(u,-1,u);
106     {
107         int v=e.to[j]; if(use[v]) continue;
108         G=0; tsz=sz[v]; gra(v,-1); fa[G]=u;
109         main_dfs(G);
110     }
111 }
112 void modify(int x,int K,int w)
113 {
114     int i,D;
115     for(i=x;i;i=fa[i])
116     {
117         D=dis(x,i);
119         if(!fa[i]) break;
120         D=dis(x,fa[i]);
122     }
123 }
124 int query(int x)
125 {
126     int i,D,ans=0;
127     for(i=x;i;i=fa[i])
128     {
129         D=dis(x,i);
131         if(!fa[i]) break;
132         D=dis(x,fa[i]);
134     }
135     return ans;
136 }
137
138 int main()
139 {
140     scanf("%d%d",&n,&m);
141     int i,j,x,y,w,ans=0;
142     for(i=1;i<n;i++) x=gint(), y=gint(), e.ae(x,y), e.ae(y,x);
143     tr::init();
144     ms[0]=tsz=n; G=0; gra(1,-1); gra(G,-1);
145     main_dfs(G); char str[10];
146     for(i=1;i<=m;i++)
147     {
148         scanf("%s",str);
149         if(str[0]=='M'){
150             x=gint(); y=gint(); w=gint();
151             modify(x,y,w);
152         }else{
153             x=gint();
154             ans=query(x);
155             printf("%d\n",ans);
156         }
157     }
158     return 0;
159 }

posted @ 2018-12-31 09:43  瓜皮大哥丶  阅读(...)  评论(...编辑  收藏