hdu 5269 ZYB loves Xor I BestCoder Round #44

题意:

ZYB喜欢研究Xor,现在他得到了一个长度为之和为多少.由于答案可能过大,,你需要输出答案对998244353取模后的值定义lowbit(x)=的数特别地:lowbit(0)=0

输入描述

一共)组数据,对于每组数据:第一行一个正整数,表示数组长度第二行

输出描述

每组数据输出一行Case #x: ans。x表示组数编号,从1开始。ans为所求值。

输入样例

254 0 2 7 052 6 5 4 0

输出样例

Case #1: 36Case #2: 40官方题解:我们考虑,当位肯定相同于是我们维护一颗字母树,将每个数表示成二进制数后翻转可以下,插入字母树统计答案时,我们找出,且当前为第的数的个数为trans(x,v^1)的子树大小。trans(x,v)表示字母树上在结点x,走连出去的字母为v的边到达的结点时间复杂度:总结:

1.这道题一直拖着没有写总结,感觉一直没有从变化中观察到不变

2.当时自己比赛没有做出来这个题目,可能当时校赛得了第7,导致有些自负吧,其实还是能力的不足,好的行为并没

有培养成好的习惯。

3.后来也是看了一眼bc群上的说trie,才想到的,下面总结一下失败的原因吧。

4.我开始是想对于除0以外的数按lowbit值排序(也就是最低位出现的1排序),lowbit相同的再按照除此位的lowbit排

序,没搞出来。

5.如果刚才的思路清晰之后,其实就是分层处理,按lowbit值相同的为一组,对于不同组直接可以算出,对于同组,减

掉刚才的lowbit,再求lowbit,继续分组运算。

6.这不就是不停地分层处理吗?!那可以用trie这种数据结构直接来做

7.比赛时候没有把算法考虑清楚就急忙写代码,以后不许再犯相同的大忌了

#include<iostream>#include<cstring>#include<cstdio>#include<algorithm>using namespace std;typedef long long LL;#define MAXN 5000500#define lowbit(i) ((i) & (-(i)))#define MOD 998244353struct Trie{int ch[MAXN][2],val[MAXN],cnt;LL ans;void init(){ans = cnt = val[0] = ch[0][0] = ch[0][1] = 0;}void insert(int v){val[0]++;int deep = 0,num = val[0],next = 0;for(int i = 0;i < 30;i++){int c = v & 1;if(!ch[next][c]){ch[next][c] = ++cnt;val[cnt] = ch[cnt][0] = ch[cnt][1] = 0;}val[ch[next][c]]++;deep++;ans += ((num – val[ch[next][c]]) << deep);ans %= MOD;next = ch[next][c];v >>= 1;num = val[next];}}}trie;int main(){int _,n,cur;for(int kcas = scanf("%d",&_);kcas <= _;kcas++){trie.init();for(int i = scanf("%d",&n);i <= n;i++){scanf("%d",&cur);trie.insert(cur);}printf("Case #%d: %I64d\n",kcas,trie.ans);}}

带着感恩的心启程,学会爱,爱父母,爱自己,爱朋友,爱他人。

hdu 5269 ZYB loves Xor I BestCoder Round #44

相关文章:

你感兴趣的文章:

标签云: