zoukankan      html  css  js  c++  java
  • 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
  • 相关阅读:
    HDU 1058 Humble Numbers
    HDU 1160 FatMouse's Speed
    HDU 1087 Super Jumping! Jumping! Jumping!
    HDU 1003 Max Sum
    HDU 1297 Children’s Queue
    UVA1584环状序列 Circular Sequence
    UVA442 矩阵链乘 Matrix Chain Multiplication
    DjangoModels修改后出现You are trying to add a non-nullable field 'download' to book without a default; we can't do that (the database needs something to populate existing rows). Please select a fix:
    opencv做的简单播放器
    c++文件流输入输出
  • 原文地址:https://www.cnblogs.com/starve/p/13635398.html
Copyright © 2011-2022 走看看