poj3384

#include<bits/stdc++.h>
using namespace std;
const int maxn=1e5+7,maxm=2e5+7;
typedef long long ll;
inline ll read(){
    ll s = 0, w = 1; char ch = getchar();
    while (ch < 48 || ch > 57) { if (ch == '-') w = -1; ch = getchar(); }
    while (ch >= 48 && ch <= 57) s = (s << 1) + (s << 3) + (ch ^ 48), ch = getchar();
    return s * w;
}
int head[maxn],to[maxm],Next[maxm],tot;
int dep[maxn],f[maxn],size[maxn],son[maxn];
int top[maxn],id[maxn],rk[maxn],dfn;
int n,m,qi,mod,a[maxn];
void add(int x,int y) {
    to[++tot]=y;
    Next[tot]=head[x];
    head[x]=tot;
}
void dfs1(int x) {
    size[x]=1,dep[x]=dep[f[x]]+1;
    for(int i=head[x],v;i;i=Next[i]) {
        v=to[i];
        if(v==f[x]) continue;
        f[v]=x;
        dfs1(v);
        size[x]+=size[v];
        if(size[son[x]]<size[v]) son[x]=v;
    }
}
void dfs2(int x,int tp) {
    top[x]=tp,id[x]=++dfn,rk[dfn]=x;
    if(son[x]) dfs2(son[x],tp);
    for(int i=head[x],v;i;i=Next[i]) {
        v=to[i];
        if(v==f[x]||v==son[x]) continue;
        dfs2(v,v);
    }
}
ll sum[maxn<<2],lazy[maxn<<2];
void push_down(int rt,int m) {
    if(lazy[rt]) {
        (lazy[rt<<1]+=lazy[rt])%=mod;
        (lazy[rt<<1|1]+=lazy[rt])%=mod;
        (sum[rt<<1]+=(m-(m>>1))*lazy[rt])%=mod;
        (sum[rt<<1|1]+=(m>>1)*lazy[rt])%mod;
        lazy[rt]=0;
    }
}
#define lson l,mid,rt<<1
#define rson mid+1,r,rt<<1|1
void build(int l,int r,int rt) {
    lazy[rt]=0;
    if(l==r) {
        sum[rt]=a[rk[l]];
        return;
    }
    int mid=(l+r)>>1;
    build(lson);
    build(rson);
    (sum[rt]=sum[rt<<1]+sum[rt<<1|1])%=mod;
}
void update(int a,int b,ll c,int l,int r,int rt){
    if(a<=l&&b>=r) {
        (sum[rt]+=(r-l+1)*c)%mod;
        (lazy[rt]+=c)%=mod;
        return;
    }
    push_down(rt,r-l+1);
    int mid=(l+r)>>1;
    if(a<=mid)    update(a,b,c,lson);
    if(b>mid)    update(a,b,c,rson);
    (sum[rt]=sum[rt<<1]+sum[rt<<1|1])%=mod;
}
ll query(int a,int b,int l,int r,int rt) {
    if(a<=l&&b>=r)    return sum[rt];
    push_down(rt,r-l+1);
    int mid=(l+r)>>1;
    ll ans=0;
    if(a<=mid)    ans+=query(a,b,lson);
    if(b>mid)    ans+=query(a,b,rson);
    return ans%mod;
}
void Subupdate(int x,int y,ll c) {
    while(top[x]!=top[y]) {
        if(dep[top[x]]<dep[top[y]]) swap(x,y);
        update(id[top[x]],id[x],c,1,n,1);
        x=f[top[x]];
    }
    if(id[x]>id[y]) swap(x,y);
    update(id[x],id[y],c,1,n,1);
}
ll Subquery(int x,int y) {
    ll res=0;
    while(top[x]!=top[y]) {
        if(dep[top[x]]<dep[top[y]]) swap(x,y);
        (res+=query(id[top[x]],id[x],1,n,1))%=mod;
        x=f[top[x]];
    }
    if(id[x]>id[y]) swap(x,y);
    return (res+query(id[x],id[y],1,n,1))%mod;
}
int main() {
    n=read(),m=read(),qi=read(),mod=read();
    for(int i=1;i<=n;++i) a[i]=read();
    for(int i=2,u,v;i<=n;++i) {
        u=read(),v=read();
        add(u,v),add(v,u); 
    }
    dfs1(qi),dfs2(qi,qi);
    build(1,n,1);
    for(int i=1,op,x,y,z;i<=m;++i) {
        op=read(),x=read();
        if(op==1) {
            y=read(),z=read();
            Subupdate(x,y,z);
        }
        else if(op==2) {
            y=read();
            printf("%lld\n",Subquery(x,y));
        }
        else if(op==3) {
            z=read();
            update(id[x],id[x]+size[x]-1,z,1,n,1);
        }
        else printf("%lld\n",query(id[x],id[x]+size[x]-1,1,n,1));
    }
}

[NOI2015]软件包管理器








#include<bits/stdc++.h>
using namespace std;
const int maxn=1e5+7,maxm=1e5+7;
typedef long long ll;
inline ll read(){
    ll s = 0, w = 1; char ch = getchar();
    while (ch < 48 || ch > 57) { if (ch == '-') w = -1; ch = getchar(); }
    while (ch >= 48 && ch <= 57) s = (s << 1) + (s << 3) + (ch ^ 48), ch = getchar();
    return s * w;
}
int head[maxn],to[maxm],Next[maxm],tot;
int dep[maxn],f[maxn],size[maxn],son[maxn];
int top[maxn],id[maxn],rk[maxn],dfn;
int n;
void add(int x,int y) {
    to[++tot]=y;
    Next[tot]=head[x];
    head[x]=tot;
}
void dfs1(int x) {
    size[x]=1,dep[x]=dep[f[x]]+1;
    for(int i=head[x],v;i;i=Next[i]) {
        v=to[i];
        f[v]=x;
        dfs1(v);
        size[x]+=size[v];
        if(son[x]==-1||size[son[x]]<size[v]) son[x]=v;
    }
}
void dfs2(int x,int tp) {
    top[x]=tp,id[x]=++dfn,rk[dfn]=x;
    if(~son[x]) dfs2(son[x],tp);
    for(int i=head[x],v;i;i=Next[i]) {
        v=to[i];
        if(v==son[x]) continue;
        dfs2(v,v);
    }
}
ll sum[maxn<<2],lazy[maxn<<2];
void push_down(int rt,int m) {
    if(lazy[rt]!=-1) {
        lazy[rt<<1]=lazy[rt];
        lazy[rt<<1|1]=lazy[rt];
        sum[rt<<1]=(m-(m>>1))*lazy[rt];
        sum[rt<<1|1]=(m>>1)*lazy[rt];
        lazy[rt]=-1;
    }
}
#define lson l,mid,rt<<1
#define rson mid+1,r,rt<<1|1
void update(int a,int b,ll c,int l,int r,int rt){
    if(a<=l&&b>=r) {
        sum[rt]=(r-l+1)*c;
        lazy[rt]=c;
        return;
    }
    push_down(rt,r-l+1);
    int mid=(l+r)>>1;
    if(a<=mid)    update(a,b,c,lson);
    if(b>mid)    update(a,b,c,rson);
    sum[rt]=sum[rt<<1]+sum[rt<<1|1];
}
ll query(int a,int b,int l,int r,int rt) {
    if(a<=l&&b>=r)    return sum[rt];
    push_down(rt,r-l+1);
    int mid=(l+r)>>1;
    ll ans=0;
    if(a<=mid)    ans+=query(a,b,lson);
    if(b>mid)    ans+=query(a,b,rson);
    return ans;
}
ll Subquery(int x,int y) {
    ll res=0,tmp;
    while(top[x]!=top[y]) { 
        if(dep[top[x]]<dep[top[y]]) swap(x,y);
        res+=id[x]-id[top[x]]+1-query(id[top[x]],id[x],1,n,1);
        update(id[top[x]],id[x],1,1,n,1);
        x=f[top[x]];
    }
    if(id[x]>id[y]) swap(x,y);
    tmp=query(id[x],id[y],1,n,1);
    update(id[x],id[y],1,1,n,1);
    return res+id[y]-id[x]+1-tmp;
}
string s;
int main() {
    n=read();
    for(int i=1,u;i<n;++i) {
        u=read();
        add(u,i); 
    }
    memset(son,-1,sizeof son);//zhu yi
    memset(lazy,-1,sizeof lazy);
    dfs1(0),dfs2(0,0);
    int q=read();
    for(int i=1,x;i<=q;++i) {
        cin>>s;    x=read();
        if(s=="install") {
            cout<<Subquery(x,0)<<endl;
        }
        else {
            cout<<query(id[x],id[x]+size[x]-1,1,n,1)<<endl;
            update(id[x],id[x]+size[x]-1,0,1,n,1);
        }
    }
}