[SHOI2012]魔法树 链剖

来源:互联网 发布:盗版软件 知乎 编辑:程序博客网 时间:2024/05/10 17:46

都是链剖基础操作,注意开long long


码:

#include<iostream>#include<cstdio>#include<vector>using namespace std;#define zuo o<<1,l,mid#define you o<<1|1,mid+1,rint x,y,a,b,i,n,q,cnt,fu[100005],sz[100005],d[100005<<2],hson[100005],top[100005],dui[100005],op,rt;char ch[10];long long c,v[100005<<2],bj[100005<<2];vector<int>va[100005];void dfs1(int o,int dis){int i;sz[o]=1;d[o]=dis;for(i=0;i<va[o].size();i++){int nd=va[o][i];dfs1(nd,dis+1);if(sz[nd]>sz[hson[o]])hson[o]=nd;sz[o]+=sz[nd];}} void dfs2(int o,int tap){ int i; top[o]=tap; dui[o]=++cnt; if(hson[o])dfs2(hson[o],tap);    for(i=0;i<va[o].size();i++){int nd=va[o][i];if(nd==hson[o])continue;dfs2(nd,nd);    }  }void down(int o,long long l,long long r){if(bj[o]){long long mid=(l+r)>>1;v[o<<1]+=(mid-l+1)*bj[o];v[o<<1|1]+=(r-mid)*bj[o];bj[o<<1]+=bj[o];bj[o<<1|1]+=bj[o];bj[o]=0;}}void up(int o){v[o]=v[o<<1]+v[o<<1|1];}void gai(int o,long long l,long long r){if(a<=l&&r<=b){if(op==1){v[o]+=(r-l+1)*c;    bj[o]+=c;}else c+=v[o];return ;}long long mid=(l+r)>>1;down(o,l,r);if(a<=mid)gai(zuo);if(b>mid)gai(you);up(o);}void work(int x,int y){while(top[x]!=top[y]){if(d[top[x]]<d[top[y]])swap(x,y);a=dui[top[x]];b=dui[x];gai(1,1,n);x=fu[top[x]];}if(d[x]<d[y])swap(x,y);a=dui[y],b=dui[x];gai(1,1,n);}int main(){scanf("%d",&n);rt=1;for(i=1;i<n;i++){scanf("%d%d",&b,&a);b++;a++;fu[a]=b;va[fu[a]].push_back(a);}dfs1(rt,1);dfs2(rt,rt);scanf("%d",&q);while(q--){scanf("%s",ch);if(ch[0]=='A'){scanf("%d%d%lld",&x,&y,&c);x++;y++;op=1;work(x,y);}else{scanf("%d",&x);x++;op=0;c=0;a=dui[x],b=dui[x]+sz[x]-1;gai(1,1,n);printf("%lld\n",c);}}}


原创粉丝点击