FZU2277 Change(dfs序+树状数组)

来源:互联网 发布:佳能网络打印机设置ip 编辑:程序博客网 时间:2024/06/04 19:44

题意

q次操作,操作有两种:
1 v x k:a[v]+=x,a[v’]+=x-k(v’是v的子节点)…
2 v:查询

Sample Input

131 131 1 2 12 12 2

Sample Output

21

这个地方的思路应该是一种套路。多学学。。
可以参考https://vjudge.net/solution/10068685的。。
我的代码不知道什么地方错了。re。。。

int fst[N],vv[N<<1],nxt[N<<1],tot;int dep[N];LL xval[N<<2],kval[N<<2];int n;int sid[N],tid[N];void add(int u,int v){    vv[tot]=v;nxt[tot]=fst[u];fst[u]=tot++;}void dfs(int u,int fa){    sid[u]=++cnt;    for(int i=fst[u];~i;i=nxt[i]){        int v=vv[i];        if(v==fa)continue;        dep[v]=dep[u]+1;        dfs(v,u);    }    tid[u]=cnt;}inline int lowbit(int x){return x&(-x);}void upx(int x,LL val){    while(x<=n){        xval[x]=(xval[x]+val)%mod;        x+=lowbit(x);    }}void upk(int x,LL val){    while(x<=n){        kval[x]=(kval[x]+val)%mod;        x+=lowbit(x);    }}LL  qx(int x){    LL ret=0;    while(x){ ret=(ret+xval[x])%mod; x-=lowbit(x); }    return ret;}LL qk(int x){    LL ret=0;    while(x){ ret=(ret+kval[x])%mod; x-=lowbit(x); }    return ret;}int main(){    int T;sf("%d",&T);    while(T--){        mem(dep,0);mem(fst,-1);tot=0;mem(kval,0);mem(kval,0);cnt=0;        sf("%d",&n);        rep(i,2,n){ int x;sf("%d",&x);add(i,x);add(x,i); }        dep[1]=0;        dfs(1,1);        int q;sf("%d",&q);        while(q--){            LL op,v,x,k;sf("%lld",&op);            if(op==1){                sf("%lld%lld%lld",&v,&x,&k);                upk(sid[v],k); upx(sid[v],(x+(k*dep[v])%mod)%mod);                upk(tid[v]+1,-k);upx(tid[v]+1,-(x+(x*dep[v])%mod)%mod);            }            else{                sf("%lld",&v);                LL x=qx(sid[v]);                LL k=qk(sid[v]);                pf("%lld\n",(x-k*dep[v]%mod+mod)%mod);            }        }    }}
阅读全文
0 0
原创粉丝点击