CQOI2015 选数
发布日期:2021-08-17 00:51:55 浏览次数:2 分类:技术文章

本文共 1087 字,大约阅读时间需要 3 分钟。

粘题目描述:

我们知道,从区间[L,H](L和H为整数)中选取N个整数,总共有(H-L+1)^N种方案。

小z很好奇这样选出的数的最大公约数的规律,他决定对每种方案选出的N个整数都求一次最大公约数,以便进一步研究。

然而他很快发现工作量太大了,于是向你寻求帮助。

你的任务很简单,小z会告诉你一个整数K,你需要回答他最大公约数刚好为K的选取方案有多少个。由于方案数较大,你只需要输出其除以1000000007的余数即可。

题解:

容斥+递推。如果我们在区间[l,r]种任取n个不全相同的数时,他们的gcd一定<=r-l+1(贝祖)。

然后就很好搞了,l=(l+k-1)/k,h=h/k。

然后f[ i ]表示合法区间内选n个数不全相同且gcd==i的方案。

容斥之前是x^n-x,然后逆向处理即可。

代码:

#include
#include
#include
using namespace std;#define MOD 1000000007#define N 100050#define ll long longint n,k,l,h;ll f[N];ll fastpow(ll x,int y){ ll ret = 1ll; while(y) { if(y&1)ret=ret*x%MOD; x=x*x%MOD; y>>=1; } return ret;}int main(){ scanf("%d%d%d%d",&n,&k,&l,&h); l=(l+k-1)/k,h=h/k; for(int i=1;i<=(h-l+1);i++) { int x = (h/i)-((l+i-1)/i)+1; f[i]=fastpow(x,n)-x; } for(int i=(h-l+1);i>=1;i--) { for(int j=2;i*j<=(h-l+1);j++) { f[i]=(f[i]-f[i*j]+MOD)%MOD; } } printf("%lld\n",f[1]+(l==1)); return 0;}

 

转载于:https://www.cnblogs.com/LiGuanlin1124/p/10048188.html

转载地址:https://blog.csdn.net/weixin_30825199/article/details/99152547 如侵犯您的版权,请留言回复原文章的地址,我们会给您删除此文章,给您带来不便请您谅解!

上一篇:工作流笔记第二天_流程定义的CRUD
下一篇:dotnet core 之 CORS使用示例

发表评论

最新留言

很好
[***.229.124.182]2024年04月15日 00时05分59秒