zoukankan      html  css  js  c++  java
  • 牛客練習賽32 B-Xor-Path 技巧題

    原題:題目鏈接

      題目大意:

      給定一棵樹,求樹上所有點對之間路徑上的值的異或和,即對所有點對( i , j )n >= i >= 1,n >= j >= 1且i != j,這些所有的點對間路徑上的值的異或和,的異或和

      解題大意:

      根據Xor的性質,同一個數抑或偶數次為0,奇數次為它本身,所以只要知道一個節點值被Xor的次數,就知道它對答案有沒有貢獻,最後把那些被Xor奇數次的值,即Xor後不為0的值,求它們的Xor和就是答案。

      這裡DFS一遍,就可以算出每個節點被Xor多少次。一個節點被Xor的次數分成兩部分,從它出發到其他(n-1)個節點的路徑數,和經過它的路徑數。算經過它的路徑時,就有點技巧:

      怎樣不重不漏地算出這些節點經過它的兩兩之間的路徑數。對於一個結點,搜它的子樹,記已經搜到的節點數為sum,每次搜一個枝,得到temp個點,temp*sum,就是這temp個節點與sum個節點間經過本節點的路徑數,然後把temp加到sum裡面去,繼續搜下一個枝,進行同樣的操作即可,然後再考慮子樹節點與非子樹節點間的路徑。仔細思考就能發現這就不重不漏了。之前想到複雜度很高的方法,TLE了

    AC代碼:

    #include<bits/stdc++.h>
    using namespace std;
    typedef long long ll;
    const int mod = 1e9+7;
    const int N = 1e6;
    int n,m,cnt;
    int head[N];
    int val[N];
    bool f[N];
    struct Edge
    {
        int to,next;
    }e[N];
    
    void add(int u,int v)
    {
        e[cnt].to=v;
        e[cnt].next=head[u];
        head[u]=cnt++;
    }
    int dfs(int now,int fa)
    {
        int sum=0;
            long long t=0;
        int temp;
        for(int i=head[now];i!=-1;i=e[i].next)
        {
            if(e[i].to!=fa)
            {
                temp=dfs(e[i].to,now);    //每次搜索上來
                t+=(temp*sum)%2;    //與之前搜到的和相乘,即可,只判斷奇偶,%2即可
                sum+=temp;
            }
        }
            t=(t+n-1)%2;    //從本節點出發的路徑
            t+=((n-sum-1)*sum)%2;    //所有從子樹節點出發,到非子樹節點的路徑
        if(t%2)
            f[now]=1;
        return sum+1;
    }
    int main()
    {
        memset(f,0,sizeof(f));
        memset(head,-1,sizeof(head));
        scanf("%d",&n);
        int u,v;
        for(int i=1;i<n;++i)
        {
            scanf("%d%d",&u,&v);
            add(u,v);
            add(v,u);
        }
        for(int i=1;i<=n;++i)
            scanf("%d",&val[i]);
        dfs(1,-1);
        int a=0;
        for(int i=1;i<=n;++i)
        {
            if(f[i])
            a^=val[i];
        }
        printf("%d
    ",a);
    }    
  • 相关阅读:
    定时任务框架APScheduler学习详解
    Python list 和 str 互转
    python多个变量赋值
    python数据类型转换
    jquery datetimepicker 配置参数
    c#判断是否为合法的email地址
    SQL的四种连接-左外连接、右外连接、内连接、全连接
    SQL表连接查询(inner join、full join、left join、right join)
    简单的日期转换
    递归
  • 原文地址:https://www.cnblogs.com/Lin88/p/10073267.html
Copyright © 2011-2022 走看看