zoukankan      html  css  js  c++  java
  • 牛客练习赛58 F XOR TREE

    考虑到异或两次就会相消

    经过分析发现

    • 如果路径的长度是奇数个点,那么等效于所有偶数次序的点被记录一次
    • 如果路径长度是偶数个点,那么所有点都被计入一次

    考虑到次序这个东西可以用深度相邻黑白染色来实现,我们把树拆成两份,黑色一份,白色一份

    黑色树上只记录黑色点的权值,白色点权值全部为零,白色树反之

    偷懒直接上树链剖分,最后记得处理一下 LCA 上的答案

    #include <bits/stdc++.h>
    using namespace std;
    
    const int N = 1000005;
    vector <int> g[N];
    int n,m,a[N],t1,t2,t3;
    int fa[N],siz[N],f[N],dep[N],wson[N],dfn[N],top[N],ind,tot;
    
    void dfs1(int p) {
        siz[p]=1;
        for(int q:g[p]) {
            if(q==fa[p]) continue;
            fa[q]=p;
            dep[q]=dep[p]+1;
            dfs1(q);
            siz[p]+=siz[q];
            if(siz[q]>siz[wson[p]]) wson[p]=q;
        }
    }
    
    void dfs2(int p) {
        dfn[p]=++ind;
        if(wson[p]) {
            top[wson[p]]=top[p];
            dfs2(wson[p]);
        }
        for(int q:g[p]) {
            if(q==fa[p]) continue;
            if(q==wson[p]) continue;
            top[q]=q;
            dfs2(q);
        }
    }
    
    struct tree {
        int a[1000005];
        void modify(int p,int l,int r,int pos,int key) {
            if(l==r) a[p]=key;
            else {
                if(pos<=(l+r)/2) modify(p*2,l,(l+r)/2,pos,key);
                else modify(p*2+1,(l+r)/2+1,r,pos,key);
                a[p]=a[p*2]^a[p*2+1];
            }
        }
        int query(int p,int l,int r,int ql,int qr) {
            if(l>qr || r<ql) return 0;
            if(l>=ql&&r<=qr) return a[p];
            return query(p*2,l,(l+r)/2,ql,qr)^query(p*2+1,(l+r)/2+1,r,ql,qr);
        }
        int lca(int x,int y) {
            for(;top[x]!=top[y];dep[top[x]]>dep[top[y]]?x=fa[top[x]]:y=fa[top[y]]);
            return dep[x]<dep[y]?x:y;
        }
        int dist(int x,int y) {
            int l=lca(x,y);
            return dep[x]+dep[y]-2*dep[l];
        }
        void tmodify(int p,int key) {
            modify(1,1,n,dfn[p],key);
        }
        int lquery(int p) {
            int ans=0;
            while(p) {
                int t=top[p];
                ans^=query(1,1,n,dfn[t],dfn[p]);
                p=fa[t];
            }
            return ans;
        }
        int tquery(int p,int q) {
            int l=lca(p,q);
            int ans=query(1,1,n,dfn[l],dfn[l]);
            ans^=lquery(p);
            ans^=lquery(q);
            return ans;
        }
    } A,B;
    
    signed main() {
        ios::sync_with_stdio(false);
        cin>>n>>m;
        for(int i=1;i<=n;i++) {
            cin>>a[i];
        }
        for(int i=1;i<n;i++) {
            cin>>t1>>t2;
            g[t1].push_back(t2);
            g[t2].push_back(t1);
        }
        dep[1]=1;
        dfs1(1);
        top[1]=1;
        dfs2(1);
        for(int i=1;i<=n;i++) {
            if(dep[i]&1) A.tmodify(i,a[i]);
            else B.tmodify(i,a[i]);
        }
        for(int i=1;i<=m;i++) {
            cin>>t1>>t2>>t3;
            if(t1==1) {
                a[t2]=t3;
                if(dep[t2]&1) A.tmodify(t2,a[t2]);
                else B.tmodify(t2,a[t2]);
            }
            else {
                int d=A.dist(t2,t3);
                if(d%2==0) {
                    if(dep[t2]&1) {
                        cout<<B.tquery(t2,t3)<<endl;
                    }
                    else {
                        cout<<A.tquery(t2,t3)<<endl;
                    }
                }
                else {
                    cout<<(A.tquery(t2,t3)^B.tquery(t2,t3))<<endl;
                }
            }
        }
    }
    
  • 相关阅读:
    Using Spark's "Hadoop Free" Build
    关于Consul
    关于Eureka
    关于Gateway
    关于Ribbon
    关于Hystrix
    关于Feign
    关于SpringBoot
    关于架构
    关于敏捷开发Scrum(一)
  • 原文地址:https://www.cnblogs.com/mollnn/p/12380636.html
Copyright © 2011-2022 走看看