社区讨论

卡常大佬请进

P8292[省选联考 2022] 卡牌参与者 37已保存回复 54

讨论操作

快速查看讨论及其快照的属性,并进行相关操作。

当前回复
54 条
当前快照
1 份
快照标识符
@mlgxxxeh
此快照首次捕获于
2026/02/11 02:35
上周
此快照最后确认于
2026/02/11 18:50
上周
查看原帖
写的正解,时间复杂度 O(214×maxsi×(14+log(maxsi)+214×c)O(2^{14}\times \max s_i\times (14+\log (\max s_i)+2^{14}\times \sum c),没问题(题解也是这个复杂度)。
然后你告诉我,这正解一分都没有?写暴力也要有 1010 分吧?
CPP
#include<bits/stdc++.h>
#define int long long
using namespace std;
const int N=2005,P=2000,M=(1<<14)+5,K=1e6+5;
const int p=998244353;
int n,a[N],c[310][M],m,b[18050],dp[M],g[M];
int p2[K],inv2[K];
vector<int> pr;
bool not_pr[N];
int min_fac[N],pc[N];
void add(int &x,int y){
	x=(x+y)%p;
	if(x<0) x+=p;
}
void sol(){
	cin>>m;
	for(int i=1;i<=m;i++){
		cin>>b[i];
	}
	sort(b+1,b+m+1);
	m=unique(b+1,b+m+1)-b-1;
	memset(dp,0,sizeof(dp));
	dp[0]=p2[n];
	for(int i=1;i<=m;i++){
		for(int l=0;l<(1<<14);l++){
			if(!dp[l]) continue;
			if(pc[b[i]]<14){
				int u=pc[b[i]];
				add(g[l],dp[l]);
				add(g[l^(1<<u)],dp[l]*(p-1)%p*inv2[c[u][l]]);
			}
			else{
				int u=pc[b[i]];
				add(g[l],dp[l]);
				add(g[l],dp[l]*(p-1)%p*inv2[c[u][l]]);
			}
		}
		memcpy(dp,g,sizeof(dp));
		memset(g,0,sizeof(g));
	}
	int ans=0;
	for(int l=0;l<(1<<14);l++){
		add(ans,dp[l]);
	}
	cout<<ans<<"\n";
}
void init(){
	for(int i=2;i<=P;i++){
		if(!not_pr[i]){
			pr.push_back(i);
			pc[i]=pr.size()-1;
			min_fac[i]=i;
		}
		for(int j:pr){
			if(i*j>P) break;
			not_pr[i*j]=1;
			min_fac[i*j]=j;
			if(i%j==0) break;
		}
	}
	p2[0]=inv2[0]=1;
	for(int i=1;i<K;i++){
		p2[i]=p2[i-1]*2%p;
		inv2[i]=inv2[i-1]*((p+1)/2)%p;
	}
}
signed main(){
	freopen("card.in","r",stdin);
	freopen("card.out","w",stdout);
	ios::sync_with_stdio(0),cin.tie(0);
	cin>>n;
	init();
	for(int i=1;i<=n;i++){
		int x;
		cin>>x;
		a[x]++;
	}
	for(int l=0;l<(1<<14);l++){
		for(int i=1;i<=P;i++){
			int ok=1;
			for(int j=0;j<14;j++){
				if((l>>j)&1){
					if(i%pr[j]==0){
						ok=0;
						break;
					}
				}
			}
			if(ok){
				int w=i;
				while(w>1){
					int v=min_fac[w];
					while(w%v==0) w/=v;
					c[pc[v]][l]+=a[i];
				}
			}
		}
	}
	int q;
	cin>>q;
	while(q--){
		sol();
	}
}

回复

54 条回复,欢迎继续交流。

正在加载回复...