PAROVI(ZJNU 1830)

题目大意

对于1n的数字,我们称二元组(x,y)为质数对当且仅当(x,y)=1。现在你要取若干组质数对使得i[2,n],都不满足x,y<ix,y>=i,问有多少种质数对的取法。(n<=20)

思路

由于直接做有点抽象,于是我们考虑容斥。首先我们可以O(n4)求出所有区间的质数对的个数,然后用状压枚举出满足条件的i,对于这样的几个i,我们能算出使它们满足条件的方案数,最后再利用一下容斥的性质,就能轻松AC惹~

代码

#include<bits/stdc++.h>
using namespace std;
long long mod=1e9;
int sum[25][25];
int gcd(int a,int b){return b?gcd(b,a%b):a;}
long long poww(long long a,long long n)
{
	long long ans=1;
	while(n)
	{
		if(n&1)ans=ans*a%mod;
		a=a*a%mod;n>>=1;
	}
	return ans;
}
int main()
{
	int n;
	scanf("%d",&n);
	if(n==1)
	{
		printf("0\n");
		return 0;
	}
	for(int i=1;i<=n;i++)
		for(int j=i+1;j<=n;j++)
			for(int k=i;k<=j;k++)
				for(int l=k+1;l<=j;l++)
					if(gcd(k,l)==1)sum[i][j]++;
	long long ans=0;
	vector<int>v;
	for(int i=0;i<(1<<(n-1));i++)
	{
		v.clear();
		int cnt=0;
		int anss=0;
		v.push_back(1);
		for(int j=0;j<n-1;j++)
		{
			if((1<<j)&i)
			{
				v.push_back(j+2);
				cnt++;
			}
		}
		for(int j=1;j<(int)v.size();j++)
			anss+=sum[v[j-1]][v[j]-1];
		anss+=sum[v[cnt]][n];
		if(cnt&1)ans=(ans-poww(2,anss)+1+mod)%mod;
		else ans=(ans+poww(2,anss)-1+mod)%mod;
	}
	printf("%lld\n",ans);
	return 0;
}

__EOF__

本文作者Jerry-Black
本文链接https://www.cnblogs.com/Jerry-Black/p/16455888.html
关于博主:小蒟蒻一只( ̄^ ̄)ゞ
版权声明:转载请注明来源哟~ QAQ
声援博主:UP UP UP !!!
posted @   Jerry_Black  阅读(20)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· winform 绘制太阳,地球,月球 运作规律
· AI与.NET技术实操系列(五):向量存储与相似性搜索在 .NET 中的实现
· 超详细:普通电脑也行Windows部署deepseek R1训练数据并当服务器共享给他人
· 【硬核科普】Trae如何「偷看」你的代码?零基础破解AI编程运行原理
· 上周热点回顾(3.3-3.9)
点击右上角即可分享
微信分享提示