skkyk:題解 洛谷P2420 【讓咱們異或吧】lca+xor前綴和

剛學了LCA,寫篇題解鞏固一下node

首先題目有誤: (A是不是男生 )xor( B是不是男生)=A和B是否可以成爲情侶這句話顯然是錯誤的qwqios

對於這道題,容易看出,對於待處理的兩個點,只要咱們找到他的最近公共祖先,問題便遊刃而解了數組

因此個人思路就是:lca+xor前綴和函數


這是個人大法師函數spa

yihuo數組就是保存當前節點到根節點的xor值code

推算了一下,對於xor前綴和有: 兩個點x,y間的的xor值=yihuo[x]^yihuo[y]io

void dfs(int f,int father,int XOR)
{
    depth[f]=depth[father]+1;
    fa[f][0]=father;
    yihuo[f]=XOR;
    for(int i=1;(1<<i)<=depth[f];i++)
        fa[f][i]=fa[fa[f][i-1]][i-1];
    for(int i=head[f];i;i=edge[i].next)
        if(edge[i].to!=father)
            dfs(edge[i].to,f,XOR^edge[i].dis);
}

剩下的就是普通的lca,在深層節點向上跳的每一個過程當中class

記錄下待求的ansstream

具體實現見代碼循環

#include<iostream>
#include<cstdio>
using namespace std;
int n,m,cnt,ans;
#define N 100000+1
int fa[N][22];
struct node {
    int next,to,dis;
} edge[N<<1];
int head[N],yihuo[N],lg[N],depth[N],a[N];
inline void add(int from,int to,int dis) {
    edge[++cnt].to=to;
    edge[cnt].next=head[from];
    edge[cnt].dis=dis;
    head[from]=cnt;
}
void dfs(int f,int father,int XOR) {
    depth[f]=depth[father]+1;
    fa[f][0]=father;
    yihuo[f]=XOR;
    for(int i=1; (1<<i)<=depth[f]; i++)
        fa[f][i]=fa[fa[f][i-1]][i-1];
    for(int i=head[f]; i; i=edge[i].next)
        if(edge[i].to!=father)
            dfs(edge[i].to,f,XOR^edge[i].dis);
}
void lca(int x,int y) {
    if(depth[x]<depth[y])
        swap(x,y);
    while(depth[x]>depth[y]) {
        ans=ans xor yihuo[x] xor yihuo[fa[x][lg[depth[x]-depth[y]]-1]];
        x=fa[x][lg[depth[x]-depth[y]]-1];
    }
    if(x==y)
        return ;
    for(int i=lg[depth[x]]-1; i>=0; i--) {//2019710改,這個地方的循環開始以前寫錯了,可是提交卻ac了..
        if(fa[x][i]!=fa[y][i]) {
            ans=ans xor yihuo[x] xor yihuo[fa[x][i]];
            ans=ans xor yihuo[y] xor yihuo[fa[y][i]];
            x=fa[x][i],y=fa[y][i];
        }
    }
    ans=ans xor yihuo[x] xor yihuo[y] ;
}
int main() {
    scanf("%d",&n);
    for(int i=1; i<=n-1; i++) {
        int u,v,dis;
        scanf("%d%d%d",&u,&v,&dis);
        add(u,v,dis),add(v,u,dis);
    }
    for(int i=1; i<=n; i++)
        lg[i]=lg[i>>1]+1;
    dfs(1,0,0);
    scanf("%d",&m);
    for(int i=1,x,y; i<=m; i++) {
        ans=0;
        scanf("%d%d",&x,&y);
        lca(x,y);
        printf("%d\n",ans);
    }
    return 0;
}

留個贊再走吧qwq

相關文章
相關標籤/搜索