ビットセットのエクササイズ

問題の意味

ここに画像を挿入説明
間で A [ ] < = 2 K [I] <= 2 ^ K n個 * K < = 2 E 6 N * K <= 2E6 バツ = = 3 X == 3
データ・パーティション
大きいkの場合のために、CAN n個 2 * K N ^ 2 * k個 暴力、ハンドビットセットによってそこに最適化することができ
、それらがn知らないので、kのように可変長配列の使用(及び実際には同じベクター)、ここで
トン P S チップ: 可変長配列は、実際には配列へのポインタであり、あなたが通常の使用に手動で割り当て初期値を必要とする。
小さいkに対して、3の寄与を検討するための電力:
これらの位置を厳選列挙3つの位置は、XORの結果であります数の条件満たすためのプログラム1.計算
彼らの排他的論理和の結果を検討する理由は、我々は最後だけ、我々はXORは、それぞれの場所を構成する他の二つのプログラムが必要であることをプログラムの4種類を列挙するために計算のみ8種類(あります)1、他の4つは、カウントされたである。
その後、我々は排他的論理和の入力の各々にプログラムの数を決定することができる。
算出されたソリューションを満たすの今数条件:
COEプログラムの表示順序位置を表します数のみhが順序を記録することなく、プログラムを記録したためである。
この複雑です n個 * K 3 N * K ^ 3

#include<bits/stdc++.h>
using namespace std;
#define ull unsigned long long
const int maxn=2e6+5;
const int mod=998244353;
inline int read(){
	char c=getchar();int t=0,f=1;
	while(!isdigit(c)){if(c=='-')f=-1;c=getchar();}
	while(isdigit(c)){t=(t<<3)+(t<<1)+(c^48);c=getchar();}
	return t*f;
}
int n,k,x;
unsigned int seed;
unsigned int get01(){
	seed^=seed<<13;
	seed^=seed>>17;
	seed^=seed<<5;
	return seed&1;
}
unsigned int *a[maxn],b[maxn];
inline int am(int x){
	return x>=mod?x-mod:x;
}
int pre[maxn];
inline int ksm(int a,int b){
	int ans=1;
	while(b){
		if(b&1)ans=1ll*ans*a%mod;
		a=1ll*a*a%mod;b>>=1;
	}
	return ans;
}
int g[maxn],h[60][60][60][8];
signed main(){
	n=read(),k=read(),x=read();
	scanf("%u",&seed);
	if(k>=60){
		int len=(k-1)/32+1;
		for(int i=1;i<=n;i++){
			a[i]=b+i*len;
			for(int j=0;j<k;j++){
				if(get01()){
					a[i][j>>5]=a[i][j>>5]+(1u<<(j%32));
				}
			}
		}
		pre[0]=1;
		for(int i=1;i<=len;i++)pre[i]=ksm(2,i*32);
		unsigned int ans=0;
		for(int i=1;i<=n;i++){
			for(int j=i+1;j<=n;j++){
				unsigned int tmp=0;
				for(int k=0;k<len;k++){
					tmp=am(tmp+(ull)(a[i][k]^a[j][k])*pre[k]%mod);
					//printf("%d %u %u %d %u\n",k,a[i][k],a[j][k],pre[k],tmp);
				}
				ans=am(ans+1ll*tmp*tmp%mod*tmp%mod);
			}
		}
		printf("%u\n",ans);
		return 0;
	}
	int ans=0;
	pre[0]=1;
	for(int i=1;i<=n;i++)pre[i]=2ll*pre[i-1]%mod;
	for(int i=1;i<=n;i++){
		for(int j=0;j<k;j++)
		g[j]=get01();
		for(int k1=0;k1<k;k1++)
		for(int k2=k1;k2<k;k2++)
		for(int k3=k2;k3<k;k3++){
			//printf("%d %d %d %d\n",k1,k2,k3,g[k1]|(g[k2]<<1)|(g[k3]<<2));
			h[k1][k2][k3][g[k1]|(g[k2]<<1)|(g[k3]<<2)]++;
		}
	}
	for(int k1=0;k1<k;k1++){
		for(int k2=k1;k2<k;k2++){
			for(int k3=k2;k3<k;k3++){
				for(int r=0;r<4;r++){
					int q=7^r,coe=1;
					if((k1!=k2)&&(k2!=k3))coe=6;
					else if((k1!=k2)||(k2!=k3))coe=3;
					coe=1ll*coe*h[k1][k2][k3][q]%mod*h[k1][k2][k3][r]%mod;
					ans=am(ans+1ll*pre[k1]*pre[k2]%mod*pre[k3]%mod*coe%mod);
				}
			}
		}
	}
	printf("%d\n",ans%mod);
}
公開された62元の記事 ウォンの賞賛1 ビュー985

おすすめ

転載: blog.csdn.net/wmhtxdy/article/details/103875665