题目大意是说给一棵特殊的树,除了1之外所有点的度数<=2,每个点存有一个值,初值都是0
之后给出两种树上操作:
0:将到某个点v的距离<=d的所有点权值加上x
1:输出某点v的权值
第一眼看错题了,以为是修改一条链上的所有点的值,发现是水题,开始BIT搞……之后发现看错题了,不是给两点链操作而是按距离,果断删代码……
又看了几眼,发现确实是BIT……很不爽地隔了很长时间才重新搞这题……
直接粘代码……
/*
把1号节点去掉就是一堆链,dfs找链染色确定下标,在链上的整体操作可以用BIT c维护
把所有点放到一起,处理出来每个颜色的区间,问题就解决了一半……
另一半是跨越1的问题,这里值只和深度有关
处理出来每个点的深度dep[],那么超过1的再用另一个BIT c1存起来
每个点的值就是c.get(pos[v])+c1.get(dep[v]) ?
其实还有一个问题……
假设对vv进行了修改,跨越了1,c1的更新是针对所有链,相当于vv所在链重复计算了……
所以要在修改点所在链开始,长度为d-dep[vv]的一段减去x
剩下的就是堆代码
*/
#include <iostream>
#include <cstring>
using namespace std;
#define N 200005
#define _int long long
#define max(a,b) ((a)>(b)?(a):(b))
#define min(a,b) ((a)<(b)?(a):(b))
struct BIT {
_int n,c[N+1]; void init(int s) {n=s; memset(c,0,sizeof(c));}
void change(int p, _int k) {for (; p<=n; p+=p&-p) c[p]+=k;}
_int sum(int p) {_int s=0; for (; p; p-=p&-p) s+=c[p]; return s;}
};
struct BIT_ex {
BIT t; void init(int s) {t.init(s);}
void change(int l, int r, _int k) {t.change(l,k); t.change(r+1,-k);}
_int get(int p) {return t.sum(p);}
};
struct {int p,next;} e[N];
BIT_ex c,c1;
int g[N],col[N],p[N],dep[N],st[N],ed[N],tot=0,len=0,ans1=0;
void addedge(int a,int b) {e[++tot].p=b; e[tot].next=g[a]; g[a]=tot;}
void dfs(int now,int pre,int coo,int dee) {
col[now]=coo; p[now]=++len; dep[now]=dee;
if (dee==1) st[coo]=len; bool last=true;
for (int tmp=g[now]; tmp; tmp=e[tmp].next)
if (e[tmp].p!=pre) {last=false; dfs(e[tmp].p,now,coo,dee+1);}
if (last) ed[coo]=len;
}
int main() {
int n,q; cin >> n >> q;
memset(g,0,sizeof(g));
for (int i=1; i<n; i++) {
int u,v; cin >> u >> v;
addedge(u,v); addedge(v,u);
}
for (int tmp=g[1],coo=1; tmp; tmp=e[tmp].next) {
dfs(e[tmp].p,1,coo,1); coo++;
}
c.init(len); c1.init(len);
while (q--) {
int t,v; cin >> t >> v;
if (t) {
if (v==1) cout << ans1 << endl;
else cout << c.get(p[v])+c1.get(dep[v]) << endl;
} else {
int x,d; cin >> x >> d;
if (v==1) {c1.change(1,d,x); ans1+=x;}
else {
c.change(max(p[v]-d,st[col[v]]),min(p[v]+d,ed[col[v]]),x);
if (d>=dep[v]) {
ans1+=x;
if (d>dep[v]) {
c1.change(1,d-dep[v],x);
c.change(st[col[v]],min(st[col[v]]+d-dep[v]-1,ed[col[v]]),-x);
}
}
}
}
}
//system("pause");
return 0;
}
p.s.其实这个实现并不好……如果把每个链当成不同的BIT限定好起点终点来做,应该还能提高效率,懒人路过……