首页 > 其他分享 >P8292 [省选联考 2022] 卡牌

P8292 [省选联考 2022] 卡牌

时间:2022-12-24 09:33:44浏览次数:58  
标签:P8292 14 省选 质数 容斥 maxp int 联考 mod

https://www.luogu.com.cn/problem/P8292

题解

先把小于等于\(\sqrt{2000}\)的质数打一个表,发现只有\(14\)个,其中第\(14\)个是\(43\).

令前\(14\)个质数为小质数,其它的为大质数.

一个数因式分解后最多只会含有一个大质数.

于是,我们可以令\(f[s][i]\)表示含有第\(i\)个大质数,小质数的选择情况为\(s\)的子集的数字个数.

这样,给定的\(n\)个数就被划分成了两部分,要么含有大质数,要么不含大质数.

假设询问的小质数的集合为\(S\).

考虑每一个大质数,如果包含在询问中,它至少选一个,选法为\(2\)的幂减\(1\),如果没有包含在询问中,它可选可不选,选法为\(2\)的幂.注意,最后答案还应该包括满足条件的小质数随便选.

假设我们把集合\(s\)按照如上方法求得的答案为\(F[s]\).

如果只求\(F[S]\),必然会使得一些方案并不包含集合\(S\).

这怎么办呢?

可以考虑容斥.

对于\(S\),我们考虑枚举没有选择的\(1\)个小质数强制它不选,减去它的\(F\),但是这会使得没有选择\(2\)个小质数的方案被多减,于是要加上它的\(F\).

最后我们发现这是一个容斥系数为\(-1\)的幂的容斥.

时间复杂度为\(O(C2 ^ {14}m+2 ^ {14} \sum _ i c _ i)\),其中\(C\)为一个较大的常数.

总结

考试的时候发现了质数个数很少的性质,但过度关注了质因子的组合情况很多,而忽略了一个数至多只含一种大质数的性质.

1.与质因数有关的题目,要想到大于等于\(\sqrt{N}\)的数只含有一种大质因子的性质.

2.要求满足集合\(S\)的方案数,可以考虑求满足集合\(S\)子集的方案数再容斥,或对补集的子集进行容斥.

代码

#include <bits/stdc++.h>
using namespace std;
const int maxp = 2000;
const int maxn = 1e6;
const int mod = 998244353;
int inc(int x, int y) {	return (x + y >= mod) ? (x + y - mod) : (x + y); }
int dec(int x, int y) { return (x - y < 0) ? (x - y + mod) : (x - y); }
int mul(int x, int y) {	return 1ll * x * y % mod; }
int mo(int x) { return (x % mod + mod) % mod; }
int n, m;
int tot, p[maxp + 5], pid[maxp + 5], cnt[maxp + 5];
int f[304][1 << 14], a[18005], pw[maxn + 5];
bool vis[maxp + 5];
void sieve() {
	for(int i = 2; i <= maxp; i++) {
		if(!vis[i])
			p[++tot] = i, pid[i] = tot;
		for(int j = 1; j <= tot; j++) {
			vis[i * p[j]] = 1;
			if(i % p[j] == 0) break;
			if(i * p[j] > maxp) break;
		}
	}
}
int main() {
	ios::sync_with_stdio(0);
	cin.tie(0);
	sieve();
	int lim = 1;
	while(p[lim + 1] * p[lim + 1] <= maxp)
		lim++;
	cin >> n;
	for(int i = 1, x; i <= n; i++) {
		cin >> x;
		cnt[x]++;
	}
	// O(2 ^ 14 * 2000 * C)
	for(int s = 0; s < (1 << lim); s++) {
		for(int i = 1; i <= maxp; i++) vis[i] = 0;
		for(int i = 1; i <= lim; i++)
			if((1 << (i - 1)) & s)
				for(int j = 1; j * p[i] <= maxp; j++)
					vis[p[i] * j] = 1;
		for(int i = 1; i <= maxp; i++)
			if(!vis[i])
				f[0][s] = inc(f[0][s], cnt[i]);
		for(int i = lim + 1; i <= tot; i++)
			for(int j = 1; j * p[i] <= maxp; j++)
				if(!vis[j * p[i]])
					f[i][s] = inc(f[i][s], cnt[j * p[i]]);
	}
	pw[0] = 1;
	for(int i = 1; i <= n; i++)
		pw[i] = mul(pw[i - 1], 2);
	cin >> m;
	// O(2 ^ 14 * 300 * 1500)
	// O(2 ^ 14 * 1500)
	while(m--) {
		int k;
		cin >> k;
		for(int i = 1; i <= k; i++)
			cin >> a[i];
		sort(a + 1, a + 1 + k);
		k = unique(a + 1, a + 1 + k) - a - 1;
		int ss = 0, si = k + 1;
		for(int i = 1; i <= k; i++)
			if(pid[a[i]] <= lim)
				ss |= (1 << (pid[a[i]] - 1));
			else {
				si = i;
				break;
			}
		int ans = 0;
		for(int s = ss; ; s = (s - 1) & ss) {
			int res = 1, t = f[0][s];
			for(int i = si; i <= k; i++) {
				res = mul(res, pw[f[pid[a[i]]][s]] - 1);
				t = dec(t, f[pid[a[i]]][s]);
			}
			res = mul(res, pw[t]);
			if(__builtin_parity(s))
				ans = dec(ans, res);
			else
				ans = inc(ans, res);
			if(s == 0) break;
		}
		cout << ans << '\n';
	}
	return 0;
}

标签:P8292,14,省选,质数,容斥,maxp,int,联考,mod
From: https://www.cnblogs.com/yanchengzhi/p/17002033.html

相关文章

  • 省选11. 字符串
    P3426[POI2005]SZA-Template考虑dp,设\(f(i)\)表示前\(i\)字符所需要的最小印章。\(f(i)\)要么等于\(i\),要么等于\(f(nxt(i))\)。如果存在\(j\geqn-nxt(i)\),......
  • 省选知识点做题记录
    luogu[IOI2014]Wall砖墙题解可以转化为区间取\(min\)和区间取\(max\).规定一下下传标记的顺序推一下式子就行了.[NOIP2013提高组]华容道题解先想到了朴素的......
  • 省选07. 多项式
    P3338[ZJOI2014]力\[\begin{aligned}E_i&=\sum_{j=1}^{i-1}\frac{q_j}{(i-j)^2}-\sum_{j=i+1}^n\frac{q_j}{(i-j)^2}\end{aligned}\]设\(f(x)=q_x\),\(g(x)=x^2\),\(h(......
  • 省选08. 组合计数
    P4091[HEOI2016/TJOI2016]求和有一个重要的通项公式\[\begin{Bmatrix}n\\m\end{Bmatrix}=\sum_{i=0}^{m}\frac{i^n(-1)^{m-i}}{i!(m-i)!}\]\[ans=\sum_{i=0}^{n}\sum......
  • 省选09. 图论
    P2469[SDOI2010]星际竞速可以发现,一个点要么是起点,要么从其它点进入,且每个点最多只会进入一次,出去一次。因此,可以用流量限制每个点被访问一次,用费用计算代价,问题就转化......
  • 省选10. 动态规划
    P3736[HAOI2016]字符合并考虑区间dp+状压dp。设\(dp(l,r,s)\)表示\([l,r]\)合并成\(s\)的最大分数。如果\(r-l+1=len\),那么合并后的长度一定是\(len\bmod{......
  • 省选05. 线性代数
    P6772[NOI2020]美食家先假设没有美食节,容易得到一个矩阵优化的dp。加上美食节过后分成\(k\)段考虑,每段分别矩阵快速幂,时间复杂度为\(O((5n)^3k\logT)\)。这并不......
  • 省选06. 分治
    CF1442DSum设\(dp(i,j)\)表示前\(i\)个数组选\(j\)个元素的最大值。\[dp(i,j)=\max_{k=0}^jdp(i-1,k)+sum(i,k)\]因为数组内的元素单调不降,因此有一个结论,只有一......
  • 省选03. 树上问题
    P2664树上游戏首先,将贡献拆成每种颜色对每个点的贡献。考虑已经选择了一种颜色,将这些颜色的点和所对应边全部删去,就得到了很多连通块。假设其中一个连通块的大小为\(s......
  • 省选04. 数论
    P4571[JSOI2009]瓶子和燃料先对两个容量分别为\(a\),\(b\)的瓶子考虑。可以发现,无论是倒入还是倒出,体积都是\(a\)或\(b\)的整数倍。因此可以考虑求\(ax+by\)的......