1. 程式人生 > >bzoj4017 小Q的無敵異或 數學

bzoj4017 小Q的無敵異或 數學

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

       首先看第一問。令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{log A})。

       然後看第二問,繼續考慮第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]<sum[x-1] 且 sum[x-1]-sum[y]<=2^k即可,用樹狀陣列維護即可。時間複雜度O(NlogNlog sum|A|)。

AC程式碼如下:

#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#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){
	for (; x<=cnt; x+=x&-x) c[x]^=t;
}
int getxor(int x){
	int t=0; for (; x; x-=x&-x) t^=c[x];
	return t;
}
int find(ll x){
	if (x<0) return 0; int l=1,r=cnt+1;
	while (l+1<r){
		int mid=(l+r)>>1;
		if (hash[mid]<=x) l=mid; else r=mid;
	}
	return l;
}
int main(){
	scanf("%d",&n); int i; ll k,ans=0;
	for (i=1; i<=n; i++){
		scanf("%d",&a[i]); sum[i]=sum[i-1]^a[i];
		m=max(m,sum[i]);
	}
	for (k=1; k<=m; k<<=1){
		c[0]=1; c[1]=0;
		for (i=1; i<=n; i++){
			int tmp=(sum[i]&k)?1:0;
			ans=(ans+k*c[tmp^1]%mod)%mod; c[tmp]++;
		}
	}
	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){
		for (i=0; i<=n; i++) num[i]=p[i]=sum[i]&((k<<1)-1);
		sort(num,num+n+1); hash[cnt=1]=num[0];
		memset(c,0,sizeof(c));
		for (i=1; i<=n; i++)
			if (num[i]!=num[i-1]) hash[++cnt]=num[i];
		int tmp=0;
		for (i=0; i<=n; i++){
			tmp^=getxor(find(p[i]-k))^getxor(find(p[i]))^getxor(find(p[i]+k));
			ins(find(p[i]),1);	
		}
		if (tmp) ans|=k;
	}
	printf("%lld\n",ans);
	return 0;
}


by lych

2016.2.27

相關推薦

bzoj4017 Q無敵 數學

        一般和異或相關的求和都是一位一位來的。這題也一樣。        首先看第一問。令sum[i]=a[1]^a[2]^...^a[i],那麼xor(l,r)=sum[l-1]^sum[r

BZOJ4017:Q無敵

長度 原因 stat con sum nlog 之前 時間復雜度 solution Link 題意:有一個長度為 \(N\) 的數列,求其 \[\sum 所有子數列異或和\] 以及\[XORSUM \{子數列求和\}\] \(1 \leq N \leq 10^5,元素 0

Q無敵 -- 所有區間的

給定一個長度為n的非負整數序列{An},求序列的所有子區間異或值之和模998244353,和所有子區間之和的異或值。 n≤105,Ai≤106。 題解: 先考慮第一問。 令xor(i)表示

xian 區域賽 g bzoj 4017: Q無敵

 求任意區間的異或和  sum(  i<j  ) 列舉右端點,記錄左端點中有多少能和它異或產生貢獻的左端點 #include <iostream> #include <cst

2017.10.12 Q無敵 失敗總結

第一問是可以O(n)的 二進位制位是獨立的,所以直接分開算即可。。 記一個字首和,開桶裝0、1的個數     然後每次新加入一個點就直接更新就可以了 第二問就比較難了,,手玩只能發現最低位可以這麼搞,對於高位還要考慮借位情況,借位情況有0有1,就不好離散 但是這麼做是可以

hdu3949(線性基,求第k

鏈接 sel time cau int another logs 題目 there 題目鏈接:http://acm.hdu.edu.cn/showproblem.php?pid=3949 XOR Time Limit: 2000/1000 MS (Java/Others)

2018.11.07【校內模擬】(數位DP)(數學期望)

傳送門 解析: 蒟蒻考場上只想了隨機情況下的期望,於是就拿了部分分滾粗了。。。 其實最優情況下的期望我好像還推錯了,最後學習了標解才會的。 我好菜啊。。。希望今年NOIP不要打醬油就行了。 思路: 首先隨機的情況其實非常好想。我們只需要考慮每個位出現

紅球進黑洞【線段樹區間更新+二進位制處理】【牛客白月賽9-C】

題目連結   給你N個點,M次查詢,問的是(一)、區間【l, r】的數的總和;(二)、把區間【l, r】上的所有點去異或(xor)一個數X。   一開始用了點更新,然後T了,想了一會,最後在比賽結束前終於美滋滋的完成了AC,慶幸,我的想法是這樣的,將每個

PAT (Basic Level) Practice 1071 賭怡情(判斷條件的優化——

問題描述: 常言道“小賭怡情”。這是一個很簡單的小遊戲:首先由計算機給出第一個整數;然後玩家下注賭第二個整數將會比第一個數大還是小;玩家下注 t 個籌碼後,計算機給出第二個數。若玩家猜對了,則系統獎勵玩家 t 個籌碼;否則扣除玩家 t 個籌碼。 注意:玩家下注的籌碼數不能

51nod1496 最

題目 令 l e n =

codeforces 888G.Xor-MST(01字典樹+貪心+最生成樹)

給你n個點,每條邊的邊權是兩個點的異或和,問你形成最小生成樹,需要的代價是多少。(n≤200000,ai≤230) 思路:把數都插到字典樹裡面,然後考慮兩個數的合併,最小代價的話,應該是儘可能相同的多,所以可以看做是兩個子樹的合併,那麼插的時候記錄一個

hdu 3949(線性基模版) 和中第k的數

傳送門 給定 n(n \le 10000)n(n≤10000) 個數 a_1, a_2, \ldots, a_na​1​​,a​2​​,…,a​n​​,以及 Q(Q\le 10000)Q(Q≤10000) 個詢問,每次詢問這些數(至少一個,不能不選)能夠組成的異或和

【ZROI】【數學相關】【計數問題】【17 提高 6】統計

首先考慮這個問題的簡化版:求∑(aixoraj)∗(ajxorak)∑(aixoraj)∗(ajxorak),這就等價於求∑j((∑aixoraj)(∑ajxorak))∑j((∑aixoraj)(∑a

運用指標,呼叫函式來是3個數從大到輸出(通過來交換大小)

今天通過對指標和函式的學習,運用異或運算來實現對3個數從大到小排序,並嘗試運用#define進行註釋,希望對初學者有所幫助。程式如下: #include<stdio.h> //#define debug #ifdef debug int main(int arg

hdu 3949 XOR 求第K

Problem Description XOR is a kind of bit operator, we define that as follow: for two binary base number A and B, let C=A XOR B, then f

51nod 1778 Q的集合 lucas定理+線性篩+數學

題意 小Q有一個集合SS,它的元素個數|S|=n|S|=n。 對於SS的任意一個子集合TT,定義f(T)=|T|kf(T)=|T|k,定義TT關於SS的補集為S−TS−T。 小Q想知道,如果他等概

牛客白月賽11 Rinne Loves Xor(運算好題)

tdi 當前 -s html lov sin 分享 bubuko ive Rinne Loves Xor 題解:   看到二進制異或就可以想一下是否可以按位處理。我們可以通過計算二進制中每一位對答案貢獻來解這個題。我們考慮異或運算會造成貢獻的唯一可能就是當前位上的二進制數

HDU 3949 XOR (第k值)

XOR Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) Total Submission(s): 1740    Accepted Submission

線性基求第k

ace http ble printf lin 題意 subset %d void 題目鏈接 題意:給由 n 個數組成的一個可重集 S,每次給定一個數 k,求一個集合 \(T \subseteq S\), 使得集合 T 在 S 的所有非空子集的不同的異或和中, 其異或和 \

樹講解(6)——讓我們

!= 情侶 rst back cst getch 能夠 代碼 st表 洛谷——P2420 讓我們異或吧 題目描述 異或是一種神奇的運算,大部分人把它總結成不進位加法. 在生活中…xor運算也很常見。比如,對於一個問題的回答,是為1