zoukankan      html  css  js  c++  java
  • ZYB loves Xor I HDU

    题意:

    T组样例,给你n个数。你要找出来这n个数中任意两个数的二进制位中  最低位不同  的位置(假设是k),然后让所有2^k加起来就是结果

    什么意思?

    例如4 和 2

    4的二进制是(100),2的二进制是(010),那么它们二进制位中 最低位不同 的位置  就是1,然后把这个2^1加入最后结果就完了

    注意:4和2算一次结果,2和4也要算一次结果

    解释个样例:

    5
    4 0 2 7 0

    sum=0

    4和0:k=2,sum+=2^2

    4和2:k=1,sum+=2^1

    4和7:k=0,sum+=2^0

    4和0:k=2,sum+=2^2

    0和2:k=1,sum+=2^1

    0和7:k=0,sum+=2^0

    0和0:因为0^0=0,题目上lowbit(0)=0,所以sum+=0

    2和7:k=0,sum+=2^0

    2和0:k=1,sum+=2^1

    7和0:k=0,sum+=2^0

    sum=4+2+1+4+2+1+0+1+2+1=18

    又因为“4和2算一次结果,2和4也要算一次结果”,所以sum*=2

    sum=36

    题解:

    观察发现对于任意一个数 x 来说,只要前 i-1 位和其它数相等,第i位不相等。那么 ans += cnt * pow(2, i-1);
     cnt 为和它前i-1个前缀都相等的数的个数。 可以利用字典树边插入边更新ans,最后ans*2就是答案。

    数组开小了TLE了半天。。。。

    代码:

     1 #include <iostream>
     2 #include <cstdio>
     3 #include <cstring>
     4 #include <cstdlib>
     5 #include <algorithm>
     6 using namespace std;
     7 typedef long long ll;
     8 const int maxn=2;
     9 const ll mod=998244353;
    10 typedef struct Trie* TrieNode;
    11 ll v[50005];
    12 ll w[31],result;
    13 struct Trie
    14 {
    15     ll val,sum;
    16     TrieNode next[2];
    17     Trie()
    18     {
    19         val=0;
    20         sum=0;
    21         memset(next,NULL,sizeof(next));
    22     }
    23 };
    24 
    25 void inserts(TrieNode root,ll x,ll y)
    26 {
    27     TrieNode p = root;
    28     for(ll i=0;i<30;++i)
    29     {
    30         ll temp=(x>>i)&1;
    31         if(p->next[temp]==NULL) p->next[temp]=new struct Trie();
    32         if(p->next[!temp]!=NULL && p->next[!temp]->sum>0)
    33         {
    34             ll t=p->next[!temp]->sum;
    35             t=(t*(ll)w[i])%mod;
    36             result=(result+t)%mod;
    37         }
    38         p->next[temp]->sum+=y;
    39         p=p->next[temp];
    40     }
    41     p->val=x;
    42 }
    43 void Del(TrieNode root)
    44 {
    45     for(ll i=0 ; i<2 ; ++i)
    46     {
    47         if(root->next[i])Del(root->next[i]);
    48     }
    49     delete(root);
    50 }
    51 
    52 int main()
    53 {
    54     ll t,n,sum=1;
    55     int p=0;
    56     w[0]=1;
    57     for(int i=1;i<=30;++i)
    58     {
    59         sum=(sum*2)%mod;
    60         w[i]=sum;
    61     }
    62     scanf("%lld",&t);
    63     while(t--)
    64     {
    65         TrieNode root = new struct Trie();
    66         scanf("%lld",&n);
    67         //ll ans=0;
    68         result=0;
    69         for(ll i=1;i<=n;++i)
    70         {
    71             scanf("%lld",&v[i]);
    72             inserts(root,v[i],1);
    73         }
    74         printf("Case #%d: %lld
    ",++p,(result<<1)%mod);
    75         Del(root);
    76     }
    77     return 0;
    78 }
  • 相关阅读:
    eclipse新建JSP页面报错:Multiple annotations found at this line解决方法
    yum 安装报错:*epel: mirrors.aliyun.comError: xzcompressionnot available
    shell脚本中定义路径变量出现的BUG
    Rsync 12种故障排查及思路
    定时清除 /var/log/massage 下的信息脚本文件
    企业集群架构之全网备份
    局域网的某个机器无法上网,的排错思路
    日志审计
    在VUE中使用富文本编辑器ueditor
    ABP框架使用 Swagger
  • 原文地址:https://www.cnblogs.com/kongbursi-2292702937/p/12001423.html
Copyright © 2011-2022 走看看