题意:给一棵树,树上的节点有权值,
给三种操作I x y k 在x到y的路径上每个点增加k
d x y k 在x到y的路径上每个节点减少k
q x 查询x节点的值
很明显的树链剖分,
树链剖分的内容查看:http://blog.sina.com.cn/s/blog_7a1746820100wp67.html
#pragma comment(linker,"/STACK:100000000,100000000")
#include
#include
#include
#include
#include
using namespace std;
#define maxn 70007
#define lc u<<1
#define rc u<<1|1
#define ll long long
struct Node{
int l,r,lz;
};
Node node[maxn<<2];
struct Edge{
int v,next;
};
Edge edge[maxn*4];
int cnt,head[maxn];
void add_edge(int u,int v){
edge[cnt].v = v, edge[cnt].next=head[u];
head[u] = cnt++;
edge[cnt].v = u, edge[cnt].next=head[v];
head[v] = cnt++;
}
int num[maxn],res[maxn],flag,check[maxn];
int fa[maxn],son[maxn],id[maxn],height[maxn],top[maxn];
void dfs1(int u,int f){
if(check[u]) return ;
check[u] =1;
height[u] = height[f]+1;
fa[u] = f;
for(int i = head[u];i != -1; i=edge[i].next){
if(check[edge[i].v]!=0)continue;
dfs1(edge[i].v,u);
if(height[edge[i].v] > height[son[u]]) son[u]=edge[i].v;
}
}
void dfs2(int u,int t){
if(check[u]) return ;
check[u] = 1;
top[u] = t;
id[u] = flag++;
res[id[u]]=num[u];
if(son[u] != 0) dfs2(son[u],t);
for(int i=head[u];i!=-1;i=edge[i].next){
dfs2(edge[i].v,edge[i].v);
}
}
void build(int u,int l,int r){
node[u].l = l,node[u].r = r;
node[u].lz = 0;
if(l == r) {
node[u].lz = res[l];
return ;
}
int mid=(l+r)/2;
build(lc,l,mid);
build(rc,mid+1,r);
}
void push(int u){
node[lc].lz+=node[u].lz;
node[rc].lz+=node[u].lz;
node[u].lz=0;
}
void add(int u,int l,int r,int d){
if(node[u].l == l && node[u].r == r){
node[u].lz+=d;
return ;
}
int mid = (node[u].l+node[u].r)/2;
push(u);
if(mid < l) add(rc,l,r,d);
else if(mid>=r)add(lc,l,r,d);
else add(lc,l,mid,d),add(rc,mid+1,r,d);
}
int getsum(int u,int p){
if(node[u].l == p && node[u].r==p)
return node[u].lz;
push(u);
int mid=(node[u].l+node[u].r)/2;
if(mid v) swap(u,v);
add(1,u,v,k);
}
}
}
return 0;
}