求助,TLE了#2 #9 #10,如何进一步优化
查看原帖
求助,TLE了#2 #9 #10,如何进一步优化
632236
gan1234楼主2022/11/5 22:19

代码应该是正确的,但是操作一操作二跑的太慢了

丑陋的代码

#include<bits/stdc++.h>
#define MAXN 100005
using namespace std;
struct Seg_Tree{
    int l,r,s,add;
}dat[MAXN*4];

int n,m,rt,mod,cnt;
vector<int>G[MAXN];
int id[MAXN],top[MAXN],son[MAXN],siz[MAXN],p[MAXN],dep[MAXN],a[MAXN];

void build(int l,int r,int k){
    dat[k].l=l;dat[k].r=r;
    if(l==r)return ;
    int m=(l+r)/2;
    build(l,m,k+k);
    build(m+1,r,k+k+1);
}
void update(int x,int y,int z,int k){
    if(dat[k].l==x&&dat[k].r==y){
        dat[k].add=(dat[k].add+z)%mod;
        return ;
    }
    int m=(dat[k].l+dat[k].r)/2;
    dat[k].s=(dat[k].s+(y-x+1)*z)%mod;
    if(y<=m)update(x,y,z,k+k);
    else if(x>m)update(x,y,z,k+k+1);
    else update(x,m,z,k+k),update(m+1,y,z,k+k+1);
}
int query(int x,int y,int p,int k){
    p=(p+dat[k].add)%mod;
    if(dat[k].l==x&&dat[k].r==y)return (p*(y-x+1)+dat[k].s)%mod;
    int m=(dat[k].l+dat[k].r)/2;
    if(y<=m)return query(x,y,p,k+k);
    else if(x>m)return query(x,y,p,k+k+1);
    else return (query(x,m,p,k+k)+query(m+1,y,p,k+k+1))%mod;
}

void dfs1(int x,int pre){
    p[x]=pre;siz[x]=1;dep[x]=dep[pre]+1;
    int l=G[x].size();
    int mxl=0;
    for(int i=0;l>i;i++)
        if(G[x][i]!=pre){
            int y=G[x][i];
            dfs1(y,x);
            siz[x]+=siz[y];
            if(G[y].size()>=mxl)son[x]=y,mxl=G[y].size();
        }
}

void dfs2(int x,int t){
    id[x]=++cnt;
    top[x]=t;
    if(a[x]!=0)update(id[x],id[x],a[x],1);
    if(son[x]==0)return ;
    dfs2(son[x],t);
    int l=G[x].size();
    for(int i=0;l>i;i++){
        int y=G[x][i];
        if(id[y])continue;
        dfs2(y,y);
    }
} 

void addpath(int x,int y,int z){
    while(top[x]!=top[y]){
        if(dep[top[x]]<dep[top[y]])swap(x,y);
        update(id[top[x]],id[x],z,1);
        x=p[top[x]];
    }
    if(dep[x]>dep[y])swap(x,y);
    update(id[x],id[y],z,1);
}
int querypath(int x,int y){
    int res=0;
    while(top[x]!=top[y]){
        if(dep[top[x]]<dep[top[y]])swap(x,y);
        res=(res+query(id[top[x]],id[x],0,1))%mod;
        x=p[top[x]];
    } 
    if(dep[x]>dep[y])swap(x,y);
    res=(res+query(id[x],id[y],0,1))%mod;
    return res;
}
void addtree(int x,int z){
    update(id[x],id[x]+siz[x]-1,z,1);
}
int querytree(int x){
    return query(id[x],id[x]+siz[x]-1,0,1);
}
signed main(){
    ios::sync_with_stdio(0);
    cin.tie(0);cout.tie(0);
    cin>>n>>m>>rt>>mod;
    for(int i=1;n>=i;i++)cin>>a[i];
    int x,y,z;
    for(int i=1;n>i;i++){
        cin>>x>>y;
        G[x].push_back(y);
        G[y].push_back(x);
    }
    build(1,n,1);
    dfs1(rt,0);
    dfs2(rt,rt);
    
    int k;
    for(int i=0;m>i;i++){
        cin>>k;
        if(k==1){
            cin>>x>>y>>z;
            addpath(x,y,z);
        }else if(k==2){
            cin>>x>>y;
            cout<<querypath(x,y)%mod<<endl;
        }else if(k==3){
            cin>>x>>z;
            addtree(x,z);
        }else{
            cin>>x;
            cout<<querytree(x)%mod<<endl;
        }
    }
    return 0;
}
2022/11/5 22:19
加载中...