[hdu5269]字典树
题意:给一个序列[a, a + n),求Σlowbit(ai, aj),i,j∈[0,n)。
思路:lowbit与位有关,于是按位统计即可,如果lowbit=2^k,则前k位相同,前缀相同,于是想到用字典树来统计。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 | #pragma comment(linker, "/STACK:10240000,10240000") #include <iostream> #include <cstdio> #include <cstring> #include <cstdlib> #include <vector> #include <algorithm> #include <queue> using namespace std; const int maxn = 2e6; const int md = 998244353; struct Trie { int ch[maxn][2], val[maxn], sz; void init() { sz = 1; memset (ch, 0, sizeof (ch)); memset (val, 0, sizeof (val)); } void insert( int x) { int p = 0, cnt = 0; while (cnt < 31) { if (ch[p][x & 1]) p = ch[p][x & 1]; else p = ch[p][x & 1] = sz ++; val[p] ++; cnt ++; x >>= 1; } } int solve( int p, int dep) { int buf = ( long long )val[ch[p][0]] * val[ch[p][1]] % md * (( long long )1 << dep) % md; if (ch[p][0]) buf = (buf + solve(ch[p][0], dep + 1)) % md; if (ch[p][1]) buf = (buf + solve(ch[p][1], dep + 1)) % md; return buf; } }; Trie solver; int main() { #ifndef ONLINE_JUDGE freopen ( "in.txt" , "r" , stdin); #endif // ONLINE_JUDGE int T, cas = 0, n; cin >> T; while (T --) { cin >> n; solver.init(); for ( int i = 0; i < n; i ++) { int x; scanf ( "%d" , &x); solver.insert(x); } printf ( "Case #%d: %d\n" , ++ cas, solver.solve(0, 1)); } return 0; } |