烁烁的游戏
写完震波那个之后会发现这俩其实是一个套路的,对应到区间上大概是"区间修改单点查询"和"单点修改区间查询"吧。
点分治就暂时学到这了。
1 /************************************************************** 2 Problem: 4372 3 User: hyghb 4 Language: C++ 5 Result: Accepted 6 Time:15188 ms 7 Memory:364928 kb 8 ****************************************************************/ 9 10 #include<bits/stdc++.h> 11 #define mid ((l+r)>>1) 12 #define Ls t[o].ls 13 #define Rs t[o].rs 14 using namespace std; 15 const int inf=1e5+10; 16 int n,m; 17 int tot,fi[inf],nxt[inf<<1],to[inf<<1]; 18 void link(int x,int y){ 19 to[++tot]=y;nxt[tot]=fi[x];fi[x]=tot; 20 } 21 namespace LCA{ 22 int top[inf],siz[inf],son[inf],fa[inf],dep[inf]; 23 void dfs1(int x){ 24 siz[x]=1; 25 for(int i=fi[x];i;i=nxt[i]){ 26 if(to[i]==fa[x])continue; 27 dep[to[i]]=dep[x]+1; 28 fa[to[i]]=x; 29 dfs1(to[i]); 30 siz[x]+=siz[to[i]]; 31 if(siz[to[i]]>siz[son[x]])son[x]=to[i]; 32 } 33 } 34 void dfs2(int x,int f){ 35 top[x]=f; 36 if(son[x])dfs2(son[x],f); 37 for(int i=fi[x];i;i=nxt[i]){ 38 if(top[to[i]])continue; 39 dfs2(to[i],to[i]); 40 } 41 } 42 int get_dis(int x,int y){ 43 int tmp=dep[x]+dep[y]; 44 while(top[x]!=top[y]){ 45 if(dep[top[x]]<dep[top[y]])swap(x,y); 46 x=fa[top[x]]; 47 } 48 return tmp-min(dep[x],dep[y])*2+1; 49 } 50 void init(){ 51 dfs1(1); 52 dfs2(1,1); 53 } 54 } 55 struct node{ 56 int ls,rs,lazy; 57 }t[inf*300]; 58 int sz; 59 void insert(int l,int r,int &o,int x){ 60 if(!o)o=++sz; 61 if(l==r)return ; 62 if(x<=mid)insert(l,mid,Ls,x); 63 else insert(mid+1,r,Rs,x); 64 } 65 void add(int l,int r,int o,int L,int R,int x){ 66 if(!o)return ; 67 if(l>=L&&r<=R){ 68 t[o].lazy+=x; 69 return ; 70 } 71 if(mid>=L)add(l,mid,Ls,L,R,x); 72 if(mid<R)add(mid+1,r,Rs,L,R,x); 73 } 74 int query(int l,int r,int o,int x,int ans){ 75 if(l==r)return ans+t[o].lazy; 76 if(mid>=x)return query(l,mid,Ls,x,ans+t[o].lazy); 77 else return query(mid+1,r,Rs,x,ans+t[o].lazy); 78 } 79 int vis[inf],fa[inf],siz[inf]; 80 int id,Min_size; 81 void getsize(int x,int f){ 82 siz[x]=1; 83 for(int i=fi[x];i;i=nxt[i]){ 84 if(vis[to[i]] || to[i]==f)continue; 85 getsize(to[i],x); 86 siz[x]+=siz[to[i]]; 87 } 88 } 89 void getrt(int x,int f,int y){ 90 int tmp=-0x3fffffff; 91 for(int i=fi[x];i;i=nxt[i]){ 92 if(vis[to[i]] || to[i]==f)continue; 93 getrt(to[i],x,y); 94 tmp=max(tmp,siz[to[i]]); 95 } 96 tmp=max(tmp,y-siz[x]); 97 if(tmp<Min_size){ 98 Min_size=tmp; 99 id=x; 100 } 101 } 102 int A[inf],B[inf]; 103 void dfs(int x,int f,int y){ 104 insert(1,n,A[y],LCA::get_dis(x,y)); 105 if(fa[y])insert(1,n,B[y],LCA::get_dis(x,fa[y])); 106 for(int i=fi[x];i;i=nxt[i]){ 107 if(vis[to[i]] || to[i]==f)continue; 108 dfs(to[i],x,y); 109 } 110 } 111 void Div(int x,int f){ 112 getsize(x,0); 113 Min_size=0x3fffffff; 114 getrt(x,0,siz[x]); 115 int rt=id; 116 vis[rt]=1; 117 fa[rt]=f; 118 dfs(rt,0,rt); 119 for(int i=fi[rt];i;i=nxt[i]){ 120 if(vis[to[i]])continue; 121 Div(to[i],rt); 122 } 123 } 124 int main() 125 { 126 scanf("%d%d",&n,&m); 127 for(int i=1;i<n;i++){ 128 int x,y; 129 scanf("%d%d",&x,&y); 130 link(x,y);link(y,x); 131 } 132 LCA::init(); 133 Div(1,0); 134 for(int i=1;i<=m;i++){ 135 char s[10]; 136 int x,d,w; 137 scanf("%s",s); 138 if(s[0]=='Q'){ 139 scanf("%d",&x); 140 int now=x; 141 int ans=0; 142 while(now){ 143 ans+=query(1,n,A[now],LCA::get_dis(x,now),0); 144 if(fa[now])ans-=query(1,n,B[now],LCA::get_dis(x,fa[now]),0); 145 now=fa[now]; 146 } 147 printf("%d\n",ans); 148 } 149 else { 150 scanf("%d%d%d",&x,&d,&w); 151 d+=2; 152 int now=x; 153 while(now){ 154 add(1,n,A[now],1,d-LCA::get_dis(now,x),w); 155 if(fa[now])add(1,n,B[now],1,d-LCA::get_dis(fa[now],x),w); 156 now=fa[now]; 157 } 158 } 159 } 160 return 0; 161 }