(容斥原理)牛客练习赛44 C 小y的质数

很久很久以前,我认为容斥原理的公式是无法实现的,因为那个公式又臭又长,实际使用时又有许多限制。

现在我才知道真的是可以写的。

之后我有可能写《离散数学》心得时候写容斥原理,这里接着这个题记录一下对容斥新的认识。

题如下:

链接:https://ac.nowcoder.com/acm/contest/634/C
来源:牛客网

时间限制:C/C++ 1秒,其他语言2秒
空间限制:C/C++ 262144K,其他语言524288K
64bit IO Format: %lld

题目描述

给出一个区间[L,R],求出[L,R]中 孪生质数有多少对。

由于这是一个区间筛质数的模板题。所以小k不屑于去写。
所以出题人只好yy了另一道题。
定义k生互质数为满足y + k与y - k互质的数。

现在给出区间[L,R],你需要输出区间内k生互质数有多少对

我们说一对k生互质数在区间[L,R]内,当且仅当y+k∈[L,R]y+k∈[L,R]且y−k∈[L,R]y−k∈[L,R]

输入描述:

一行三个数字L,R,k

输出描述:

一行一个数字表示区间[L,R]内的k生互质数的对数

示例1

输入

5 10 1

输出

2

说明

分别为(5,7),(7,9)

示例2

输入

287 11633 10

输出

4532

备注:

0≤L,R≤1018
1≤k≤1013

这里数据范围搞得很乱,推荐去原链接看题。

题目想要两个数互质既    gcd(y-k,y+k)=1,  这里 令 x=y-k     那么 我们要找  gcd(x,x+2k)=1的x。

这里  L<=x<=R-2k。

很好证明,  gcd(x,x+2k)=gcd(x,2k)。

那么  x与2k 互质时,x与x+2k互质。我们要在  L~R-2k中寻找x使得gcd(x,2k)=1。

对2k进行质因数分解,寻找区间中质因子不包含任何2k质因数的数。

这个时候我们就必须用到容斥原理了,相信大家又不是山顶洞人,我就不过多解释啥是容斥了,贴个公式吧。可以百度百科

下面是代码

#include<stdio.h>
#include<iostream>
#include<math.h>

using namespace std;

typedef long long ll;

ll prim[100]={0},con=0;

ll num(ll t){    //容斥原理
	if(t<0) return 0;
	ll res=0;
	ll i,j;
	
	for(i=0;i<(1<<con);i++){    //用i来表示质因数选择的每一种可能性
		ll p=1,f=1;            //f来表示这个可能性的符号
		for(j=0;j<con;j++){    //用j来搜索i当中的质数
			if((1<<j)&i){
				p=p*prim[j];
				f=f*(-1);
			}
		}
		res=res+(t/p)*f;       //一开始res加上集合中所有元素的数量,然后减去容斥的数量。
	}
	return res;
}

int main(){
	ll k,r,l,i;
	cin>>l>>r>>k;
	
	k=k*2;
	r=r-k;
	if((l+k)>r){
		printf("0\n");
		return 0;
	}
	 
	ll s=sqrt(k);
	for(i=2;i<s;i++){
		if(k%i==0)
			prim[con++]=i;
		while(k%i==0) k=k/i;
	}
	if(k!=1)
		prim[con++]=k;
	

	
	cout<<num(r)-num(l-1)<<endl;
	
	return 0;
}

 

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值