求助点分树
查看原帖
求助点分树
383791
Others楼主2023/5/1 17:50

表面上异或后操作 RE 了,实际上查询 WA 了,求大佬帮调。

#include <bits/stdc++.h>
#define ll long long
using namespace std;
const int N=100005;
int temp[N],siz[N],dep[N],tmp[N],tmpcnt,vis[N],n,m,u,v,op,x,y,Min,Minn,a[N],depMax,rt[N],rrt[N],lstans,ttemp[N],ttmp[N],ttmpcnt;
int tMaxdep;
vector<int> G[N],d[N],fa[N];
struct Othres {
    struct node {
        int l,r,lc,rc,sum;
    }tr[N<<6];
    int tot;
    void pushup(int p) {
        tr[p].sum=tr[tr[p].lc].sum+tr[tr[p].rc].sum;
        return ;
    }
    void build(int l,int r,int &p) {
        if(!p) p=++tot;
        tr[p].l=l,tr[p].r=r;
        if(l==r) {
            tr[p].sum=temp[l];
            return ;
        }
        int mid=l+r>>1;
        build(l,mid,tr[p].lc),build(mid+1,r,tr[p].rc);
        pushup(p);
        return ;
    }
    void build2(int l,int r,int &p) {
        if(!p) p=++tot;
        tr[p].l=l,tr[p].r=r;
        if(l==r) {
            tr[p].sum=ttemp[l];
            return ;
        }
        int mid=l+r>>1;
        build2(l,mid,tr[p].lc),build2(mid+1,r,tr[p].rc);
        pushup(p);
        return ;
    }
    void modify(int x,int p,int y) {
        if(tr[p].l==tr[p].r) {
            tr[p].sum+=y;
            return ;
        }
        int mid=tr[p].l+tr[p].r>>1;
        if(x<=mid) modify(x,tr[p].lc,y);
        else modify(x,tr[p].rc,y);
        pushup(p);
        return ;
    }
    int ask(int s,int t,int p) {
        if(s<=tr[p].l&&tr[p].r<=t) return tr[p].sum;
        int mid=tr[p].l+tr[p].r>>1,ans=0;
        if(s<=mid) ans+=ask(s,t,tr[p].lc);
        if(t>mid) ans+=ask(s,t,tr[p].rc);
        return ans;
    }
}T,T2;
void dfs(int p,int fa,int Sz) {
    siz[p]=1;
    int tmp=0;
    for(int i=0;i<G[p].size();i++) {
        if(G[p][i]!=fa&&!vis[G[p][i]]) {
            dfs(G[p][i],p,Sz);
            siz[p]+=siz[G[p][i]];
            tmp=max(tmp,siz[G[p][i]]);
        }
    }
    if(Min>max(tmp,Sz-siz[p])) Min=max(tmp,Sz-siz[p]),Minn=p;
}
void deal(int p,int Fa,int RT,int RRT) {
    fa[p].push_back(RT);
    d[p].push_back(dep[p]);
    depMax=max(depMax,dep[p]);
    tMaxdep=max(tMaxdep,dep[p]);
    temp[dep[p]]+=a[p];
    tmp[++tmpcnt]=dep[p];
    if(RRT) ttemp[dep[p]]+=a[p],ttmp[++ttmpcnt]=dep[p];
    for(int i=0;i<G[p].size();i++) {
        if(!vis[G[p][i]]&&G[p][i]!=Fa) {
            dep[G[p][i]]=dep[p]+1;
            if(RT==p) ttmpcnt=tMaxdep=0;
            deal(G[p][i],p,RT,RT==p?G[p][i]:RRT);
            if(RT==p) {
                T2.build2(0,tMaxdep,rrt[G[p][i]]);
                for(int j=1;j<=ttmpcnt;j++) ttemp[ttmp[j]]=0;
            }
        }
    }
}
void init(int p,int Sz) {
    Min=0x7f7f7f7f,Minn=0;
    dfs(p,0,Sz);
    p=Minn;
    tmpcnt=0,depMax=0;
    dep[p]=0;
    deal(p,0,p,0);
    T.build(0,depMax,rt[p]);
    for(int i=1;i<=tmpcnt;i++) temp[tmp[i]]=0;
    vis[p]=1;
    for(int i=0;i<G[p].size();i++) 
        if(!vis[G[p][i]]) 
            init(G[p][i],siz[G[p][i]]);
}
int main() {
   // freopen("P6329_1.in","r",stdin);
    scanf("%d%d",&n,&m);
    for(int i=1;i<=n;i++) scanf("%d",&a[i]);
    for(int i=1;i<n;i++) scanf("%d%d",&u,&v),G[u].push_back(v),G[v].push_back(u);
    init(1,n);
    for(int i=1;i<=m;i++) {
        scanf("%d%d%d",&op,&x,&y);
        x^=lstans,y^=lstans;
        if(op) {
            for(int j=0;j<fa[x].size();j++) {
                T.modify(d[x][j],rt[fa[x][j]],y-a[x]);
                if(j<fa[x].size()-1) T2.modify(d[x][j],rrt[fa[x][j+1]],y-a[x]);
            }
            a[x]=y;
        }else {
            lstans=0;
            for(int j=0;j<fa[x].size();j++) {
                if(y-d[x][j]>=0) lstans+=T.ask(0,y-d[x][j],rt[fa[x][j]]);
                if(j&&y-d[x][j-1]>=0) lstans-=T2.ask(0,y-d[x][j-1],rrt[fa[x][j]]);
            }
            printf("%d\n",lstans);
        }
    }
    return 0;
}
2023/5/1 17:50
加载中...