bzoj4017 小Q的無敵異或 數學

2021-07-10 04:24:49 字數 1146 閱讀 5183

一般和異或相關的求和都是一位一位來的。這題也一樣。

首先看第一問。令sum[i]=a[1]^a[2]^...^a[i],那麼xor(l,r)=sum[l-1]^sum[r],考慮每一位對答案帶來的影響。假設現在考慮二進位制第k位(從低到高)對答案的影響。

對於sum[x],它的第k位對答案的影響為2^k*t,其中t為1..x-1中sum值二進位制第k位與sum[x]不同的數的個數。那麼在k確定的情況下o(n)掃一遍即可。時間複雜度o(nmax)。

然後看第二問,繼續考慮第k位對答案的影響。令sum[i]=sum[i-1]+a[i],則sum(l,r)=sum[r]-sum[l-1],那麼第k位對答案有影響當且僅當存在奇數對(x,y),滿足x<=y且sum[x-1]和sum[y]的第k為不同。考慮在mod (2^(k+1))的意義下,任意;兩個sum[l]和sum[r],它們的第k為不同,當且僅當sum[r]-sum[l]>=2^k,或者sum[r]+2^k+1-sum[l]>=2^k。因此只需要考慮有多少對(x,y),x<=y,滿足sum[y]-sum[x-1]>=2^k 或者sum[y]

ac**如下:

#include#include#include#include#define ll long long

#define n 100005

#define mod 998244353

using namespace std;

int n,cnt,a[n],c[n]; ll m,sum[n],num[n],hash[n],p[n];

void ins(int x,int t)

int getxor(int x)

int find(ll x)

return l;

}int main()

for (k=1; k<=m; k<<=1)

} printf("%lld ",ans); ans=0;

for (i=1; i<=n; i++) sum[i]=sum[i-1]+a[i];

for (k=1; k<=sum[n]; k<<=1)

if (tmp) ans|=k;

} printf("%lld\n",ans);

return 0;

}

by lych

2016.2.27

bzoj 4017 小Q的無敵異或

time limit 20 sec memory limit 128 mb submit 593 solved 197 submit status discuss 背景 小q學習位運算時發現了異或的秘密。描述小q是乙個熱愛學習的人,他經常去維基百科 學習電腦科學。就在剛才,小q認真地學習了一系列位運...

bzoj 4017 小Q的無敵異或

time limit 20 sec memory limit 128 mb submit 736 solved 242 submit status discuss 背景 小q學習位運算時發現了異或的秘密。描述小q是乙個熱愛學習的人,他經常去維基百科 學習電腦科學。就在剛才,小q認真地學習了一系列位運...

BZOJ4017 小Q的無敵異或 位運算

題目鏈結 小q的無敵異或 好久之前做的這道題了 參照了別人的部落格 還是沒有全懂。第乙個問題維護個字首就好了,第二個問題還要用樹狀陣列維護 1 include 2 3using namespace std 45 define rep i,a,b for int i a i b i 6 define ...