37分求助

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

s18200257143 @ 2024-02-21 15:57:16

#include<bits/stdc++.h>
//#include<vector>
using namespace std;
const int N=1e5+5;
vector<int>to[N];
int size[N],son[N],fa[N],dep[N],sum[N*4],a[N];
int dfn[N],rev[N],top[N],tag[N];
int cnt,n,p;
void dfsson(int rt){
    size[rt]=1;
    dep[rt]=dep[fa[rt]]+1;
    for(int i=0;i<(int)to[rt].size();i++)
    {
        int v=to[rt][i];
        if(v==fa[rt])continue;
        fa[v]=rt;
        dfsson(v);
        size[rt]+=size[v];
        if(size[v]>size[son[rt]])
            son[rt]=v;
    }
}
void dfs(int rt){
    dfn[rt]=++cnt;
    rev[cnt]=rt;
    if(son[rt])
    {
        top[son[rt]]=top[rt];
        dfs(son[rt]);
    }
    for(int i=0;i<(int)to[rt].size();i++)
    {
        int v=to[rt][i];
        if(v!=fa[rt]&&v!=son[rt])
        {
            top[v]=v;
            dfs(v);
        }

    }
}
void push_down(int rt,int l,int r){
    int mid=(l+r)>>1; 
    tag[rt*2]+=tag[rt];
    tag[rt*2+1]+=tag[rt];
    sum[rt*2]+=(mid-l+1)*tag[rt];sum[rt*2]%=p;
    sum[rt*2+1]+=(r-mid)*tag[rt];sum[rt*2+1]%=p;
    tag[rt]=0;
}
void modify(int rt,int l,int r,int x,int y,int v){
    if(x<=l&&r<=y)
    {
        tag[rt]+=v;
        sum[rt]+=v*(r-l+1);
        sum[rt]%=p;
        return ;
    }
    if(r<x||y<l) return ;
    int mid=(l+r)>>1;
    push_down(rt,l,r);
    modify(rt*2,l,mid,x,y,v);
    modify(rt*2+1,mid+1,r,x,y,v);
    sum[rt]=sum[rt*2]+sum[rt*2+1];
    sum[rt]%=p;
}
int  query(int rt,int l,int r,int x,int y){
    if(x<=l&&r<=y)return sum[rt]%=p;
    if(r<x||y<l) return 0;
    int result=0;
    int mid=(l+r)>>1;
    push_down(rt,l,r);
    result+=query(rt*2,l,mid,x,y);
    result+=query(rt*2+1,mid+1,r,x,y);
    return result;
}
void modify_edge(int x,int y,int v){
    while(top[x]!=top[y])
    {
        if(dep[top[x]]<dep[top[y]]) swap(x,y);
        modify(1,1,n,dfn[top[x]],dfn[x],v);
        x=fa[top[x]];
    }
    if(dep[x]>dep[y]) swap(x,y);
    modify(1,1,n,dfn[x],dfn[y],v);
}
int  query_edge(int x,int y){
    int result=0;
    while(top[x]!=top[y])
    {
        if(dep[top[x]]<dep[top[y]]) swap(x,y);
        result+=query(1,1,n,dfn[top[x]],dfn[x]);
        result%=p;
        x=fa[top[x]];
    }
    if(dep[x]>dep[y]) swap(x,y);
    result+=query(1,1,n,dfn[x],dfn[y]);
    result%=p;
    return result;
}
void modify_tree(int x,int v){
    modify(1,1,n,dfn[x],dfn[x]+size[x]-1,v);
}
int  query_tree(int x){
//  cout << dfn[x] << ' ' << dfn[x] + size[x] - 1 << "aaa";
    return query(1,1,n,dfn[x],dfn[x]+size[x]-1);
}
void build(int rt,int l,int r){
    if(l==r)
    {
        sum[rt]=a[rev[l]];
        sum[rt]%=p;
//      cout << l << ' ' << rev[l] << ' ' << a[rev[l]] << endl; 
        return ;
    }
    int mid=(l+r)>>1;
    build(rt*2,l,mid);
    build(rt*2+1,mid+1,r);
    sum[rt]=sum[rt*2]+sum[rt*2+1];
    sum[rt]%=p;
}
int main()
{
    int m,root;
    cin>>n>>m>>root>>p;
    for(int i=1;i<=n;i++)
    {
        scanf("%d",&a[i]);
        a[i]%=p;
    } 
    for(int i=1;i<n;i++)
    {
        int u,v;
        scanf("%d %d",&u,&v);
        to[u].push_back(v);
        to[v].push_back(u);
    }
    top[root]=root;
    dfsson(root);
    dfs(root);
    build(1,1,n);
    while(m--)
    {
        int sign,x,y,z;
        scanf("%d",&sign);
        if(sign==1)
        {
            scanf("%d %d %d",&x,&y,&z);
            modify_edge(x,y,z);
        }
        if(sign==2)
        {
            scanf("%d %d",&x,&y);
            cout<<query_edge(x,y)<<endl;
        }
        if(sign==3)
        {
            scanf("%d %d",&x,&z);
            modify_tree(x,z);
        }
        if(sign==4)
        {
            scanf("%d",&x);
            cout<<query_tree(x)<<endl;
        }
    }
    return 0;
}

by Lizichen_licis @ 2024-02-22 09:30:49

报错信息是什么?帮我复制一个点的


by 1234567890regis @ 2024-02-29 19:57:04

我也是37分,不知道为什么错了。我是1,2,3点AC,4,5,6,7WA,8,9,10TLE,11AC。


by stickman_stickmin @ 2024-06-26 18:04:48

@1234567890regis 大佬知道错哪了吗,我也这样(


|