呵呵

来源:互联网 发布:数据字典模板 编辑:程序博客网 时间:2024/05/16 17:22

题目:
https://www.luogu.org/problemnew/show/3384#sub

WA的原因:
change时忘记push操作;

#include<iostream>#include<cstdio>#include<cstring>#include<algorithm>using namespace std;typedef long long ll;const ll MAXN=1000001;ll son[MAXN],siz[MAXN],fa[MAXN],nxt[MAXN],fst[MAXN];ll deep[MAXN],top[MAXN],inseg[MAXN],intr[MAXN],num[MAXN];ll tot,totp,n,m,r,p;struct Tree {ll l,r,sum,delta;}tree[MAXN];struct hh {ll from,to;}ma[MAXN];void build(ll f,ll t) {ma[++tot]=(hh){f,t},nxt[tot]=fst[f],fst[f]=tot;}void up(ll now) {tree[now].sum=(tree[now<<1].sum+tree[now<<1|1].sum)%p;}void dfs1(ll x,ll f){    fa[x]=f,deep[x]=deep[f]+1,siz[x]=1;    for(ll i=fst[x];i;i=nxt[i])    {        ll v=ma[i].to;        if(v==f) continue;        dfs1(v,x),siz[x]+=siz[v];        if(!son[x] || siz[son[x]]<siz[v]) son[x]=v;    }    return;}void dfs2(ll x,ll st){    top[x]=st,inseg[x]=++totp,intr[totp]=x;    if(!son[x]) return;    dfs2(son[x],st);    for(ll i=fst[x];i;i=nxt[i])    {        ll v=ma[i].to;        if(v==fa[x] || v==son[x]) continue;        dfs2(v,v);    }    return;}void push(ll now){    if(tree[now].delta)    {        tree[now<<1].sum=(tree[now<<1].sum+(tree[now<<1].r-tree[now<<1].l+1)*tree[now].delta)%p;        tree[now<<1].delta=tree[now<<1].delta+tree[now].delta;        tree[now<<1|1].sum=(tree[now<<1|1].sum+(tree[now<<1|1].r-tree[now<<1|1].l+1)*tree[now].delta)%p;        tree[now<<1|1].delta=tree[now<<1|1].delta+tree[now].delta;        tree[now].delta=0;    }    return;}void build_tree(ll now,ll l,ll r){    ll mid=(l+r)>>1;    tree[now].l=l,tree[now].r=r,tree[now].delta=0;    if(l==r) { tree[now].sum=num[intr[l]];return;}    build_tree(now<<1,l,mid),build_tree(now<<1|1,mid+1,r);    up(now);return;}void change_sum(ll now,ll l,ll r,ll v){    ll mid=(tree[now].l+tree[now].r)>>1;    if(tree[now].l>=l && tree[now].r<=r)    {tree[now].sum=((tree[now].r-tree[now].l+1)*v+tree[now].sum)%p;    tree[now].delta=tree[now].delta+v;return;}    push(now);    if(l<=mid) change_sum(now<<1,l,r,v);    if(r>=mid+1) change_sum(now<<1|1,l,r,v);    up(now);return;}ll query_sum(ll now,ll l,ll r){    ll ans=0;    if(tree[now].l>=l && tree[now].r<=r) return tree[now].sum;    push(now);    int mid=(tree[now].l+tree[now].r)>>1;    if(l<=mid) ans=ans+query_sum(now<<1,l,r);    if(r>=mid+1) ans=ans+query_sum(now<<1|1,l,r);    return ans%p;}void change_tree(ll x,ll y,ll z){    ll fx=top[x],fy=top[y];    while(fx!=fy)    {        if(deep[fx]<deep[fy]) swap(fx,fy),swap(x,y);        change_sum(1,inseg[fx],inseg[x],z),x=fa[fx],fx=top[x];    }    if(deep[x]>deep[y]) swap(x,y);    change_sum(1,inseg[x],inseg[y],z);    return;}ll query_tree(ll x,ll y){    ll ans=0,fx=top[x],fy=top[y];    while(fx!=fy)    {        if(deep[fx]<deep[fy]) swap(fx,fy),swap(x,y);        ans=(ans+query_sum(1,inseg[fx],inseg[x]))%p,x=fa[fx],fx=top[x];    }    if(deep[x]>deep[y]) swap(x,y);    ans=(ans+query_sum(1,inseg[x],inseg[y]))%p;    return ans%p;}void solve(){    ll opt,x,y,z;    scanf("%lld%lld%lld%lld",&n,&m,&r,&p);    for(int i=1;i<=n;i++) scanf("%lld",&num[i]);    for(int i=1;i<n;i++) scanf("%lld%lld",&x,&y),build(x,y),build(y,x);    dfs1(r,0),dfs2(r,r),build_tree(1,1,n);    for(int i=1;i<=m;i++)    {        scanf("%lld%lld",&opt,&x);        if(opt==1) scanf("%lld%lld",&y,&z),change_tree(x,y,z);        else if(opt==2) scanf("%lld",&y),printf("%lld\n",query_tree(x,y)%p);        else if(opt==3) scanf("%lld",&z),change_sum(1,inseg[x],inseg[x]+siz[x]-1,z);        else if(opt==4) printf("%lld\n",query_sum(1,inseg[x],inseg[x]+siz[x]-1)%p);    }    return;}int main(){    solve();    return 0;}
原创粉丝点击