BZOJ4017 小Q的无敌异或(位运算)
题目链接 小Q的无敌异或
好久之前做的这道题了……参照了别人的博客……还是没有全懂。
第一个问题维护个前缀就好了,第二个问题还要用树状数组维护……
1 #include <bits/stdc++.h> 2 3 using namespace std; 4 5 #define rep(i,a,b) for(int i(a); i <= (b); ++i) 6 #define LL long long 7 #define mod 998244353 8 9 const int N = 100000 + 10; 10 const int A = 30 + 1; 11 12 13 LL bit[N]; 14 int a[N], c[N]; 15 int n; 16 int cnt[A]; 17 LL xn[N], sum[N]; 18 int tmp; 19 LL p[N]; 20 LL ans1, ans2; 21 22 inline void update(int x){ for ( ; x <= n; x += ~x & x + 1) c[x] ^= 1;} 23 inline int query(int x){ int ret = 0; for ( ; x >= 0; x -= ~x & x + 1) ret ^= c[x]; return ret;} 24 25 inline int idx(LL x){ 26 int l = -1, r = n; 27 for (; l < r;){ 28 int mid = l + r + 1 >> 1; 29 if (p[mid] <= x) l = mid; else r = mid - 1; 30 } 31 return l; 32 } 33 34 35 int main(){ 36 37 bit[0] = 1; 38 rep(i, 1, 53) bit[i] = bit[i - 1] * 2; 39 scanf("%d", &n); 40 rep(i, 1, n){ 41 scanf("%d", a + i); 42 xn[i] = xn[i - 1] ^ a[i]; 43 sum[i] = sum[i - 1] + a[i]; 44 } 45 46 rep(k, 0, 30){ 47 cnt[0] = cnt[1] = 0; tmp = 0; 48 rep(i, 0, n){ 49 (tmp += cnt[((xn[i] >> k) & 1) ^ 1]) %= mod; 50 ++cnt[(xn[i] >> k) & 1]; 51 } 52 53 (ans1 += (LL)(bit[k] * tmp) % mod) %= mod; 54 } 55 56 ans2 = 0; 57 for (int k = 0; 1LL << k <= sum[n]; ++k){ 58 tmp = 0; 59 rep(i, 0, n) p[i] = sum[i] & ((1LL << k + 1) - 1); 60 sort(p, p + n + 1); 61 memset(c, 0, sizeof c); 62 rep(i, 0, n){ 63 LL now = sum[i] & ((1LL << k + 1) - 1); 64 update(idx(now)); 65 tmp ^= query(idx(now - (1LL << k))) ^ query(idx(now + (1LL << k))) ^ query(idx(now)); 66 } 67 if (tmp) ans2 |= 1LL << k; 68 } 69 70 71 printf("%lld %lld\n", ans1 % mod, ans2); 72 return 0; 73 74 }