37分求调

P3384 【模板】重链剖分/树链剖分

zhangshirui @ 2023-12-28 16:41:54

#include<bits/stdc++.h>
using namespace std;
#define ll long long
long long n,m,s,r; 
#include<bits/stdc++.h>
using namespace std;
const long long N=100005;
struct node{
    long long sum=0,tag_abb=0,tag_mul=1,tag_set=0,l,r,mid;bool can_tag_set=0;//l~mid,mid+1~r
}trees[N<<2];
void buid(long long id,long long l,long long r){
    if(l==r){
        trees[id].mid=trees[id].l=trees[id].r=l;
        return;
    }
    int mid=(l+r)>>1;
    buid(id<<1,l,mid);
    buid((id<<1)+1,mid+1,r);
    trees[id].mid=mid;
    trees[id].l=l;
    trees[id].r=r;
}
void updata(int where,long long vul){
    int s=1;
    while(trees[s].l!=trees[s].r){

        if(trees[s].mid<where)s<<=1,s++;
        else s<<=1;
    }
    long long k=trees[s].sum;
    s=1;
    while(trees[s].l!=trees[s].r){
        trees[s].sum-=k;
        trees[s].sum+=vul;
        if(trees[s].mid<where)s<<=1,s++;
        else s<<=1;
    }
    trees[s].sum-=k;
    trees[s].sum+=vul;
}
void push_down(int id){
    if(trees[id].l!=trees[id].r){
        trees[id<<1].tag_abb+=trees[id].tag_abb;
        trees[(id<<1)+1].tag_abb+=trees[id].tag_abb;
        trees[id<<1].tag_abb%=       ::r;
        trees[(id<<1)+1].tag_abb%= ::r;
    }
    trees[id].sum+=trees[id].tag_abb%  ::r*(trees[id].r-trees[id].l+1)%  ::r;trees[id].sum%= ::r;
    trees[id].tag_abb=0;
}
long long sum(int l,int r,int id=1){
    push_down(id);
    if(trees[id].l>=l&&trees[id].r<=r)return trees[id].sum%  ::r;
    long long ans=0;

    if(trees[id].mid>=l)ans+=sum(l,r,id<<1)%  ::r;
    ans%= ::r;
    if(trees[id].mid+1<=r)ans+=sum(l,r,(id<<1)+1)%  ::r;
    return ans% ::r;
}
void updata_abb(int l,int r,long long vul,int id=1){
    push_down(id);

    if(trees[id].l>=l&&trees[id].r<=r){
        trees[id].tag_abb+=vul;
        return;

    }trees[id].sum+=(min((long long)r,trees[id].r)-max((long long)l,trees[id].l)+1)% ::r*vul% ::r;
    trees[id].sum%= ::r;
    if(trees[id].mid>=l)updata_abb(l,r,vul,id<<1);
    if(trees[id].mid+1<=r)updata_abb(l,r,vul,(id<<1)+1);
}
void push_up(int id){
    trees[id].sum=trees[id<<1].sum+trees[(id<<1)+1].sum;
}

vector<long long> nexts[1000000];long long fa[1000000],son[1000000],hou_many_son[1000000],top[1000000],dep[1000000],ID[1000000],vuls[1000000];long long kkk=1;
void dfs_init(long long t,long long up_t,long long debug=0){
    fa[t]=up_t;
    hou_many_son[t]=1;long long k=0;
    if(up_t==t)dep[t]=1;
    for(long long i:nexts[t]){
        if(i!=up_t){
            dep[i]=dep[t]+1;
            dfs_init(i,t);
            hou_many_son[t]+=hou_many_son[i];
            if(hou_many_son[i]>k){
                k=hou_many_son[i];
                son[t]=i;
            }
        }
    }
}
void dfs_start_tree(long long t,long long up_t,long long link_head){
    top[t]=link_head;
    //tree_sum.update(kkk,vuls[t]);
    updata(kkk,vuls[t]%  ::r);
    ID[t]=kkk++;
    if(son[t])dfs_start_tree(son[t],t,link_head);
    for(long long i:nexts[t]){
        if(i!=son[t]&&i!=up_t&&i!=t){
            dfs_start_tree(i,t,i);
        }
    }
}
long long LCA_sum(long long x,long long y){
    long long j=0;
    while(top[x]!=top[y]){
        if(dep[top[x]]<dep[top[y]]){
            swap(x,y);
        }
        j+=sum(ID[x],ID[top[x]]);j%=r;
        x=top[x];
        x=fa[x];
    }
    j+=sum((dep[x]<dep[y]?ID[x]:ID[y]),(dep[x]>dep[y]?ID[x]:ID[y]));j%=r;
    return j;
}
void abb_LCA(long long x,long long y,long long up_vul){
    while(top[x]!=top[y]){
        if(dep[top[x]]<dep[top[y]]){
            swap(x,y);
        }
        updata_abb(ID[x],ID[top[x]],up_vul%  ::r);
        x=top[x];
        x=fa[x];
    }
    updata_abb((dep[x]<dep[y]?ID[x]:ID[y]),(dep[x]>dep[y]?ID[x]:ID[y]),up_vul%  ::r);
    return ;
}
void som_abb(long long x,long long vul){
    updata_abb(ID[x],ID[x]+hou_many_son[x]-1,vul%  ::r);
}
long long som_sum(long long x){
    return sum(ID[x],ID[x]+hou_many_son[x]-1)%r;
}
int main(){
    ios::sync_with_stdio(0);
    buid(1,1,N);
    cin>>n>>m>>s>>r;
    long long a,b,c,d;
    for(long long i=1;i<=n;i++)cin>>vuls[i];
    for(long long i=0;i<n-1;i++){
        cin>>a>>b;
        nexts[a].push_back(b);
        nexts[b].push_back(a);
    }
    dfs_init(s,s);
    dfs_start_tree(s,0,s); 
    for(long long i=0;i<m;i++){
        cin>>a>>b;
        if(a==1){
            cin>>c>>d;
            abb_LCA(b,c,d);
        }
        if(a==2){
            cin>>c;
            cout<<LCA_sum(b,c)<<'\n';
        }
        if(a==3){
            cin>>c;
            som_abb(b,c);
        }
        if(a==4){
            cout<<som_sum(b)<<'\n';
        }
    }
}

我自己感觉逻辑是没问题的,样例也过了,但就37分,有没有大佬帮我调一下。


by zhangshirui @ 2023-12-28 16:44:00

过了1,2,3,11,别的都是wa。(记录)


|