BZOJ 2836 魔法树 树链剖分

题目大意:维护一棵有根树,每个节点初始权值为0,支持下列操作:

1.链上+

2.子树求和

。。。。。链剖裸题- –

果然链剖这种东西想要1A实在是不咋现实- –

#include <cstdio>#include <cstring>#include <iostream>#include <algorithm>#define M 100100using namespace std;struct Segtree{Segtree *ls,*rs;long long val,mark;void* operator new (size_t){static Segtree mempool[M<<1],*C=mempool;return C++;}void Add(int x,int y,long long val){this->val+=val*(y-x+1);mark+=val;}void Push_Down(int x,int y){int mid=x+y>>1;ls->Add(x,mid,mark);rs->Add(mid+1,y,mark);mark=0;}void Build_Tree(int x,int y){int mid=x+y>>1;if(x==y) return ;(ls=new Segtree)->Build_Tree(x,mid);(rs=new Segtree)->Build_Tree(mid+1,y);}void Add(int x,int y,int l,int r,long long val){int mid=x+y>>1;if(x==l&&y==r){Add(x,y,val);return ;}Push_Down(x,y);if(r<=mid)ls->Add(x,mid,l,r,val);else if(l>mid)rs->Add(mid+1,y,l,r,val);elsels->Add(x,mid,l,mid,val),rs->Add(mid+1,y,mid+1,r,val);this->val=ls->val+rs->val;}long long Query(int x,int y,int l,int r){int mid=x+y>>1;if(x==l&&y==r)return val;Push_Down(x,y);if(r<=mid)return ls->Query(x,mid,l,r);if(l>mid)return rs->Query(mid+1,y,l,r);return ls->Query(x,mid,l,mid) + rs->Query(mid+1,y,mid+1,r);}}*tree=new Segtree;struct abcd{int to,next;}table[M<<1];int head[M],tot;int n,m;int fa[M],son[M],dpt[M],size[M],pos[M],top[M],cnt;void Add(int x,int y){table[++tot].to=y;table[tot].next=head[x];head[x]=tot;}void DFS1(int x){int i;dpt[x]=dpt[fa[x]]+1;size[x]=1;for(i=head[x];i;i=table[i].next)if(table[i].to!=fa[x]){fa[table[i].to]=x;DFS1(table[i].to);size[x]+=size[table[i].to];if(size[table[i].to]>size[son[x]])son[x]=table[i].to;}}void DFS2(int x){int i;if(son[fa[x]]==x)top[x]=top[fa[x]];elsetop[x]=x;pos[x]=++cnt;if(son[x]) DFS2(son[x]);for(i=head[x];i;i=table[i].next)if(table[i].to!=fa[x]&&table[i].to!=son[x])DFS2(table[i].to);}void Modify(int x,int y,int z){int fx=top[x],fy=top[y];while(fx!=fy){if(dpt[fx]<dpt[fy])swap(x,y),swap(fx,fy);tree->Add(1,n,pos[fx],pos[x],z);x=fa[fx];fx=top[x];}if(dpt[x]<dpt[y])swap(x,y);tree->Add(1,n,pos[y],pos[x],z);}int main(){int i,x,y,z;char p[10];cin>>n;for(i=1;i<n;i++){scanf("%d%d",&x,&y);++x;++y;Add(x,y);Add(y,x);}DFS1(1);DFS2(1);tree->Build_Tree(1,n);cin>>m;for(i=1;i<=m;i++){scanf("%s",p);if(p[0]=='A'){scanf("%d%d%d",&x,&y,&z);++x;++y;Modify(x,y,z);}else{scanf("%d",&x);++x;printf("%lld\n",tree->Query(1,n,pos[x],pos[x]+size[x]-1) );}}return 0;}

,去看日出,去散步,去欣赏大自然,

BZOJ 2836 魔法树 树链剖分

相关文章:

你感兴趣的文章:

标签云: