求助
查看原帖
求助
237530
rzh123楼主2022/10/11 19:23
#include <bits/stdc++.h>
#define gc IO::fastgc()
#define pc(c) IO::fastpc(c)
#define pcnt __builtin_popcount
using namespace std;
typedef long long ll;
typedef long long unsigned llu,ull;
namespace IO{
	char ibuf[1<<23],obuf[1<<23],*ip1=ibuf,*ip2=ibuf,*o=obuf;
	inline char fastgc(){
		return ((ip1==ip2)&&(ip2=(ip1=ibuf)+fread(ibuf,1,1<<21,stdin),ip1==ip2)?EOF:*ip1++);
	}
	inline void fastpc(char c){
		*(o++)=c;
	}
	inline ll read(){
		register ll t=0,f=1;
		register char c=gc;
		while(c!='-'&&(c<'0'||c>'9')) c=gc;
		if(c=='-') c=gc,f=-1;
		while(c>='0'&&c<='9') t=10*t+(c^48),c=gc;
		return f*t;
	}
	inline void write(ll x){
		if(!x) return (void)pc('0');
		if(x<0) pc('-'),x=-x;
		static char c[33]={""};
		static int cc=0;
		while(x) c[++cc]=x%10,x/=10;
		while(cc) pc(c[cc--]|48);
	}
	inline void flush(){
		fwrite(obuf,o-obuf,1,stdout);
	}
	struct IO_Flusher{
		inline IO_Flusher(){}
		inline ~IO_Flusher(){
			flush();
		}
	}__io_flusher_;
}
using IO::read;
using IO::write;
constexpr unsigned N=1000007,B=27;
constexpr ll P=1000000007;
int n,a[N];
ll f[B];
/*
	f[j]:选出与的结果有>=j个1的方案数 
*/
ll cnt[N]; //包含i的数的数量 
bool bit[N];
inline ll qp(ll a,ll b){
	ll s=1;
	while(b){
		if(b&1) s=s*a%P;
		a=a*a%P;
		b>>=1;
	}
	return s;
}
signed main(){
	ll ans;
	n=read();
	ans=qp(2,n)-1;
	for(register int i=1;i<=n;++i){
		a[i]=read();
	}
	for(register int i=1;i<=n;++i){
		++cnt[a[i]];
	}
//	for(register int i=1000000;i>=0;--i){
//		for(register int j=0;j<23;++j){
//			if(i&(1<<j)){
//				cnt[i^(1<<j)]+=cnt[i];
//			}
//		}
//	}
	for(register int j=0;j<23;++j){
		for(register int i=1000000;i>=0;--i){
			if(i&(1<<j)){
				cnt[i^(1<<j)]+=cnt[i];
			}
		}
	}
	for(register int i=0;i<=1000000;++i){
		int p=pcnt(i);
		f[p]+=qp(2,cnt[i])-1;
		f[p]=(f[p]%P+P)%P;
	}
	for(register int i=1;i<23;++i){
		if(i&1){
			ans-=f[i];
		}
		else{
			ans+=f[i];
		}
		ans=(ans%P+P)%P;
	}
	write(ans);
	return 0;
}

这个能过,

	for(register int j=0;j<23;++j){
		for(register int i=1000000;i>=0;--i){
			if(i&(1<<j)){
				cnt[i^(1<<j)]+=cnt[i];
			}
		}
	}

换成

	for(register int i=1000000;i>=0;--i){
		for(register int j=0;j<23;++j){
			if(i&(1<<j)){
				cnt[i^(1<<j)]+=cnt[i];
			}
		}
	}

(只换了两个 for 的顺序) 就过不了了,不知道为什么。

2022/10/11 19:23
加载中...