1. 程式人生 > 其它 >Codeforces Round #737 (Div. 2)-C

Codeforces Round #737 (Div. 2)-C

C. Moamen and XOR
題目連結

【題目大意】
給定n,k,要求統計出有多少個包含n個小於2^n的整數序列滿足其與運算結果大於等於異或運算結果
【思路】
統計每一位貢獻的答案
分成兩類

  1. 當n為奇數時,想滿足條件,n個元素每一位最多隻能與運算結果大於等於異或運算,即只能有偶數個1或者都為0或者都為1;每一位的貢獻為C_n^0 +C_n^2...也就是2 ^ (n-1),再加上全為1的情況,答案為(2 ^ (n-1)+1)^n
  2. 當n為偶數時,答案分成兩塊,從每個元素從2進位制最高位到最低來統計答案,除了全為1的情況n個元素每一位最多隻能與運算結果大於等於異或運算,所以我們先統計除了全為1的情況,(2 ^ (n-1)-1)n,這裡2
    (n-1)-1是因為n是偶數,我們統計偶數個1時包含了全為1的情況,然後再從高到底考慮每一位,如果當前位數全為1,即或運算為1,異或為0,那麼後面的二進位制數怎麼取都滿足,答案加上prod*Power(Power(2,i),n),i代表當前位之後的位數,prod位當前位之前的情況數,Power為快速冪運算;

【程式碼如下】

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int mod=1e9+7;
int Power(int x,int y){
	int r=1;
	while(y){
		if(y&1)r=1ll*r*x%mod;
		x=1ll*x*x%mod,y>>=1;
	}
	return r;
}
int main(){
	int t;
	cin>>t;
	while(t--){
		int n,k;
		cin>>n>>k;
      //  cout<<Power(Power(2,0),n)<<endl;
		int prod=1,ans=0;
		for(int i=k-1;i>=0;i--){
			if(n%2==0)ans=(ans+1ll*prod*Power(Power(2,i),n))%mod;
			int u=0;
			u=Power(2,n-1);
			if(n%2==0)u=(u-1+mod)%mod;
			if(n&1)u=(u+1)%mod;
			prod=1ll*prod*u%mod;
		}
		ans=(ans+prod)%mod;
		cout<<ans<<'\n';
	}
    return 0;
}