为什么查询时不处理空节点?
查看原帖
为什么查询时不处理空节点?
682174
yz_by楼主2023/1/29 10:27

注释是处理空节点的部分,这份代码可以AC

#include<bits/stdc++.h>
using namespace std;
inline int read(){
	char ch=getchar();
	int f=1,x=0;
	while(ch<'0'||ch>'9'){
		if(ch=='-')
			f=-f;
		ch=getchar();
	}
	while(ch>='0'&&ch<='9'){
		x=x*10+ch-'0';
		ch=getchar();
	}
	return x*f;
}
inline void work(int k){
	if(k<0){
		putchar('-');
		k=-k;
	}
	if(k>9)
		work(k/10);
    putchar(k%10+'0');
}
int n,m,cnt,first[50005],s[50005],son[50005],fa[50005],dp[50005],id[50005],rev[50005],dep[50005],tot,c[50005][2],d[2];
struct q1{
    int u,w,nex;
}a[100005];
void add(int u1,int w1){
    a[++cnt]={u1,w1,first[u1]};
    first[u1]=cnt;
}
void dfs(int u,int dad){
    fa[u]=dad;
    s[u]=1;
    dep[u]=dep[dad]+1;
    for(int i=first[u];i;i=a[i].nex){
        if(a[i].w==dad)
            continue;
        dfs(a[i].w,u);
        s[u]+=s[a[i].w];
        if(s[son[u]]<s[a[i].w])
            son[u]=a[i].w;
    }
}
void dfs2(int u,int t){
    dp[u]=t;
    id[u]=++tot;
    rev[tot]=u;
    if(!son[u])
        return ;
    dfs2(son[u],t);
    for(int i=first[u];i;i=a[i].nex){
        if(a[i].w==fa[u]||a[i].w==son[u])
            continue;
        dfs2(a[i].w,a[i].w);
    }
}
struct node{
    int lx[2],rx[2],dis[2][2];
    inline void init(){
        memset(lx,0,sizeof(lx));
        memset(rx,0,sizeof(rx));
        memset(dis,0,sizeof(dis));
    }
}tree[200005];
inline node operator +(node x,node y){//空节点合并的问题会出在dis
    node a;
    a.init();
    for(int i=0;i<2;i++){
        for(int j=0;j<2;j++){
            a.lx[i]=max({a.lx[i],x.lx[i],x.dis[i][j]+y.lx[j]});
            a.rx[i]=max({a.rx[i],y.rx[i],y.dis[j][i]+x.rx[j]});
            a.dis[i][j]=-1e9;
            for(int k=0;k<2;k++){
                a.dis[i][j]=max(a.dis[i][j],x.dis[i][k]+y.dis[k][j]);//如果这里x是空节点a.dis[i][j]只能由y.dis[i][j]转移,但是这里可能会由y.dis[i^1][j]转移过来,导致答案多算
            }
        }
    }
    return a;
}
void create(int k,int id){
    tree[k].dis[0][0]=c[id][0]?c[id][0]:-1e9;
    tree[k].lx[0]=tree[k].rx[0]=c[id][0];
    tree[k].dis[1][1]=c[id][1]?c[id][1]:-1e9;
    tree[k].lx[1]=tree[k].rx[1]=c[id][1];
    tree[k].dis[0][1]=tree[k].dis[1][0]=(c[id][0]&&c[id][1])?c[id][0]+c[id][1]:-1e9;
}
void build(int k,int l,int r){
    if(l==r){
        create(k,rev[l]);
        return ;
    }
    int mid=(l+r)>>1;
    build(2*k,l,mid);
    build(2*k+1,mid+1,r);
    tree[k]=tree[2*k]+tree[2*k+1];
}
void change(int k,int l,int r,int x,int d[]){
    if(l>x||r<x)
        return ;
    if(l==r&&l==x){
        c[rev[l]][0]=d[0];
        c[rev[l]][1]=d[1];
        create(k,rev[l]);
        return ;
    }
    int mid=(l+r)>>1;
    change(2*k,l,mid,x,d);
    change(2*k+1,mid+1,r,x,d);
    tree[k]=tree[2*k]+tree[2*k+1];
}
node query(int k,int l,int r,int x,int y){
    if(l>=x&&r<=y)
        return tree[k];
    int mid=(l+r)>>1;
    if(mid<x)
        return query(2*k+1,mid+1,r,x,y);
    if(mid+1>y)
        return  query(2*k,l,mid,x,y);
    return query(2*k,l,mid,x,y)+query(2*k+1,mid+1,r,x,y);//空节点合并会有问题,所以要分开写
}
int queried(int x,int y){
    node ansx,ansy;
    int flag=0,f=0;//处理空节点
    ansx.init();
    ansy.init();
    while(dp[x]!=dp[y]){
        if(dep[dp[x]]>dep[dp[y]]){
            // if(!flag){
            //     flag=1;
            //     ansx=query(1,1,n,id[dp[x]],id[x]);
            // }
            // else
                ansx=query(1,1,n,id[dp[x]],id[x])+ansx;
            x=fa[dp[x]];
        }
        else{
            // if(!f){
            //     f=1;
            //     ansy=query(1,1,n,id[dp[y]],id[y]);
            // }
            // else
                ansy=query(1,1,n,id[dp[y]],id[y])+ansy;
            y=fa[dp[y]];
        }
    }
    if(dep[x]>dep[y]){
        // if(flag)
            ansx=query(1,1,n,id[y],id[x])+ansx;
        // else{
        //     ansx=query(1,1,n,id[y],id[x]);
        //     flag=1;
        // }
    }
    else{
        // if(f)
            ansy=query(1,1,n,id[x],id[y])+ansy;
        // else{
        //     ansy=query(1,1,n,id[x],id[y]);
        //     f=1;
        // }
    }
    swap(ansx.lx[0],ansx.rx[0]);
    swap(ansx.lx[1],ansx.rx[1]);
    swap(ansx.dis[0][1],ansx.dis[1][0]);
    // if(!flag)
    //     ansx=ansy;
    // else if(!f)
    //     ansx=ansx;
    // else
        ansx=ansx+ansy;
    return max(ansx.lx[0],ansx.lx[1]);
}
int main(){
	n=read();
    m=read();
    for(int i=1,x,y;i<n;i++){
        x=read();
        y=read();
        add(x,y);
        add(y,x);
    }
    for(int i=1;i<=n;i++){
        char f;
        for(int j=0;j<2;j++){
            cin>>f;
            c[i][j]=(f=='.');
        }
    }
    dfs(1,0);
    dfs2(1,1);
    build(1,1,n);
    while(m--){
        char f;
        int s,t;
        cin>>f;
        s=read();
        if(f=='C'){
            for(int i=0;i<2;i++){
                char g;
                cin>>g;
                d[i]=(g=='.');
            }
            change(1,1,n,id[s],d);
        }
        else{
            t=read();
            work(queried(s,t));
            puts("");
        }
    }
	return 0;
}
2023/1/29 10:27
加载中...