• XORTREE(统计树上奇数位路径异或)


    题:https://ac.nowcoder.com/acm/problem/200191

    题意:给定一棵树,操作一:把u变为x,操作二统计u~v的最短路径中的各子路径的节点的异或和的异或和。1<=n,q<=1e5

    分析:考虑一个节点要么被异或到,要么不被异或到,只与被路径选中次数的奇偶有关。

       假设节点从u到v遍历,走过的路径长为x,总路径长为len,那么当前节点被选到的次数就为:x*(len-x)+x+(len-x)=x*(len-x)+len;

       我们发现,当路径长len为奇数的时候,结果肯定为奇数,也就意味着这次询问是询问u~v的节点的异或和;

            当路径长len为偶数的时候,结果是偶奇偶奇。。。地交替,也就意味着这次询问是询问u~v的节点的偶数位的异或和。

       那么可以根据深度的奇偶来判断路径即可,用长链剖分+BIT解决区间异或

    #include<bits/stdc++.h>
    using namespace std;
    #define pb push_back
    int read()
    {
        int x=0;
        char c=getchar();
        while(c<'0'||c>'9') c=getchar();
        while(c>='0'&&c<='9') x=(x<<1)+(x<<3)+c-'0',c=getchar();
        return x;
    }
    const int M=2e5+4;
    int fa[M],sz[M],deep[M],ans[M],dfn[M],tp[M],son[M],a[M],las[M];
    int cnt,n,q;
    vector<int>g[M];
    struct BIT{
        int tr[3][M];
        void init(){
            memset(tr,0,sizeof(tr));
        }
        void update(int id,int i,int x){
            while(i<=n)
                tr[id][i]^=x,i+=i&(-i);
        }
        int sum(int id,int i){
            int res=0;
            while(i){
                res^=tr[id][i];
                i-=i&(-i);
            }
            return res;
        }
    }t1;
    void dfs1(int u,int f){
        fa[u]=f,sz[u]=1,deep[u]=deep[f]+1;
        for(auto v:g[u]){
            if(v!=f){
                dfs1(v,u);
                sz[u]+=sz[v];
                if(sz[son[u]]<sz[v])
                    son[u]=v;
            }
        }
    }
    void dfs2(int u,int top){
        tp[u]=top;
        dfn[u]=++cnt;
        if(son[u])
            dfs2(son[u],top);
        for(auto v:g[u]){
            if(v!=fa[u]&&v!=son[u])
                dfs2(v,v);
        }
    }
    int solve(int u,int v){
        int res=0;
        ///路径长为奇数就,奇数位选,否则,全部选
        int id=( (deep[u]%2==deep[v]%2) ? (1-deep[u]%2) : 2);
        while(tp[u]!=tp[v]){
            if(deep[tp[u]]<deep[tp[v]])
                swap(u,v);
            res^=(t1.sum(id,dfn[u])^t1.sum(id,dfn[tp[u]]-1));
            u=fa[tp[u]];
        }
        if(deep[u]<deep[v])
            swap(u,v);
        res^=(t1.sum(id,dfn[u])^t1.sum(id,dfn[v]-1));
        return res;
    }
    int main(){
        t1.init();
        n=read(),q=read();
        for(int i=1;i<=n;i++)
            a[i]=read();
        for(int u,v,i=1;i<n;i++){
            u=read(),v=read();
            g[u].pb(v),g[v].pb(u);
        }
        dfs1(1,0),dfs2(1,1);
        for(int i=1;i<=n;i++){
            t1.update(deep[i]%2,dfn[i],a[i]);
            t1.update(2,dfn[i],a[i]);
            las[dfn[i]]=a[i];
        }
        while(q--){
            int op=read(),u=read(),v=read();
            if(op==1){
                t1.update(deep[u]%2,dfn[u],las[dfn[u]]^v);
                t1.update(2,dfn[u],las[dfn[u]]^v);
                las[dfn[u]]=v;
            }
            else{
                printf("%d
    ",solve(u,v));
            }
        }
        return 0;
    }
    View Code
  • 相关阅读:
    linux
    python(4)
    python(4)
    python(4)–yield实现异步
    python(4)-迭代器 和 生成器
    JavaScript函数参数问题
    文字垂直居中
    Window-document-javascript
    Java的StringTokenizer类
    Web应用与Spring MVC锁session
  • 原文地址:https://www.cnblogs.com/starve/p/13635398.html
Copyright © 2020-2023  润新知