Luogu P3172 [CQOI2015]选数

这题的反演做法好像很不可食用啊还得套一个杜教筛

我们注意到题目一个重要的性质:\(H-L\le10^5\),看起来可以好好利用一下。

我们首先转化问题,类似于许多和\(\gcd\)有关的问题,我们将原来的最大公约数\(K\)想办法变成\(1\)

这个怎么处理呢,其实很简单,将\(L\)变为\(\lceil \frac{L}{K}\rceil\),将\(R\)变为\(\lfloor\frac{H}{K}\rfloor\)。

显然这样我们把问题转化为:在\([L,H]\)种取\(N\)次数使它们的\(\gcd\)为\(1\)

然后我们考虑计算一个\(f_i\),表示选出的数的\(\gcd\)为\(i\),且选出的所有数不全相同的方案数。

那么我们借Luogu P1447 [NOI2010]能量采集的思路,考虑容斥计算\(f_i\)

我们首先求出\([L,H]\)之间\(i\)的倍数\(x\),那么先令\(f_i=x^N-x\)

但是发现这样的方案只是含有公约数,因此我们还要减去\(f_{ki}(k\in N^+,k>1)\)的答案

然后做法很明显了,倒序枚举并计算即可,复杂度根据调和级数公式为\(O(n(\ln(n)+H_n))\)

还有注意一下\(L=1\)时所有的数都可以选\(1\),因此要特判。

CODE

#include<cstdio>
#define RI register int
using namespace std;
const int N=100005,mod=1000000007;
int n,k,L,R,l,r,f[N];
inline void dec(int &x,int y)
{
    if ((x-=y)<0) x+=mod;
}
inline int quick_pow(int x,int p,int mul=1)
{
    for (;p;p>>=1,x=1LL*x*x%mod) if (p&1) mul=1LL*mul*x%mod; return mul;
}
int main()
{
    RI i,j; scanf("%d%d%d%d",&n,&k,&L,&R);
    L=L%k?L/k+1:L/k; R=R/k; for (i=1;i<=R-L;++i)
    {
        int l=L%i?L/i+1:L/i,r=R/i;
        f[i]=quick_pow(r-l+1,n); dec(f[i],r-l+1);
    }
    for (i=R-L;i;--i) for (j=i<<1;j<=R-L;j+=i) dec(f[i],f[j]);
    return printf("%d",L^1?f[1]:(f[1]+1)%mod),0;
}

原文地址:https://www.cnblogs.com/cjjsb/p/9873492.html

时间: 2024-10-12 19:50:42

Luogu P3172 [CQOI2015]选数的相关文章

BZOJ 3930: [CQOI2015]选数

3930: [CQOI2015]选数 Time Limit: 10 Sec  Memory Limit: 512 MBSubmit: 1130  Solved: 532[Submit][Status][Discuss] Description 我们知道,从区间[L,H](L和H为整数)中选取N个整数,总共有(H-L+1)^N种方案.小z很好奇这样选出的数的最大公约数的规律,他决定对每种方案选出的N个整数都求一次最大公约数,以便进一步研究.然而他很快发现工作量太大了,于是向你寻求帮助.你的任务很简

BZOJ 3930: [CQOI2015]选数 递推

3930: [CQOI2015]选数 Time Limit: 20 Sec Memory Limit: 256 MB 题目连接 http://www.lydsy.com/JudgeOnline/problem.php?id=3930 Description 我们知道,从区间[L,H](L和H为整数)中选取N个整数,总共有(H-L+1)^N种方案.小z很好奇这样选出的数的最大公约数的规律,他决定对每种方案选出的N个整数都求一次最大公约数,以便进一步研究.然而他很快发现工作量太大了,于是向你寻求帮助

【刷题】BZOJ 3930 [CQOI2015]选数

Description 我们知道,从区间[L,H](L和H为整数)中选取N个整数,总共有(H-L+1)^N种方案.小z很好奇这样选出的数的最大公约数的规律,他决定对每种方案选出的N个整数都求一次最大公约数,以便进一步研究.然而他很快发现工作量太大了,于是向你寻求帮助.你的任务很简单,小z会告诉你一个整数K,你需要回答他最大公约数刚好为K的选取方案有多少个.由于方案数较大,你只需要输出其除以1000000007的余数即可. Input 输入一行,包含4个空格分开的正整数,依次为N,K,L和H. O

BZOJ3930:[CQOI2015]选数——题解

http://www.lydsy.com/JudgeOnline/problem.php?id=3930 https://www.luogu.org/problemnew/show/P3172#sub 我们知道,从区间[L,H](L和H为整数)中选取N个整数,总共有(H-L+1)^N种方案.小z很好奇这样选出的数的最大公约数的规律,他决定对每种方案选出的N个整数都求一次最大公约数,以便进一步研究.然而他很快发现工作量太大了,于是向你寻求帮助.你的任务很简单,小z会告诉你一个整数K,你需要回答他最

BZOJ3930 [CQOI2015]选数 【容斥】

题目 我们知道,从区间[L,H](L和H为整数)中选取N个整数,总共有(H-L+1)^N种方案.小z很好奇这样选出的数的最大公约数的规律,他决定对每种方案选出的N个整数都求一次最大公约数,以便进一步研究.然而他很快发现工作量太大了,于是向你寻求帮助.你的任务很简单,小z会告诉你一个整数K,你需要回答他最大公约数刚好为K的选取方案有多少个.由于方案数较大,你只需要输出其除以1000000007的余数即可. 输入格式 输入一行,包含4个空格分开的正整数,依次为N,K,L和H. 输出格式 输出一个整数

CQOI2015 选数

粘题目描述: 我们知道,从区间[L,H](L和H为整数)中选取N个整数,总共有(H-L+1)^N种方案. 小z很好奇这样选出的数的最大公约数的规律,他决定对每种方案选出的N个整数都求一次最大公约数,以便进一步研究. 然而他很快发现工作量太大了,于是向你寻求帮助. 你的任务很简单,小z会告诉你一个整数K,你需要回答他最大公约数刚好为K的选取方案有多少个.由于方案数较大,你只需要输出其除以1000000007的余数即可. 题解: 容斥+递推.如果我们在区间[l,r]种任取n个不全相同的数时,他们的g

bzoj3930 [CQOI2015]选数

Description 我们知道,从区间[L,H](L和H为整数)中选取N个整数,总共有(H-L+1)^N种方案.小z很好奇这样选出的数的最大公约数的规律,他决定对每种方案选出的N个整数都求一次最大公约数,以便进一步研究.然而他很快发现工作量太大了,于是向你寻求帮助.你的任务很简单,小z会告诉你一个整数K,你需要回答他最大公约数刚好为K的选取方案有多少个.由于方案数较大,你只需要输出其除以1000000007的余数即可. Input 输入一行,包含4个空格分开的正整数,依次为N,K,L和H. O

3930: [CQOI2015]选数|递推|数论

题目让求从区间[L,H]中可重复的选出n个数使其gcd=k的方案数 转化一下也就是从区间[?Lk?,?Hk?]中可重复的选出n个数使其gcd=1的方案数 然后f[i]表示gcd=i的方案数,考虑去掉所有的数都是重复的情况,这种情况最后在判断一下加上 f[i]=sum?∑i|jf[j] #include<algorithm> #include<iostream> #include<cstdlib> #include<cstring> #include<c

CQOI2015 选数+酱油记

昨天我们考了CQOI2015的题..那还是找一道最可做的写一写好了>.<.. 考试的结果还是不多说了..反正我是知道暴力乱搞高精度的重要性了..骗分的OI才有随机性才好玩,嘛... 成绩不忍直视但竟然还没出前三..感人肺腑... 怎么觉得自从看了CLJ犇的Blog之后越来越喜欢模仿他们的语气卖萌了呢~~ 还是总结一下考试好了,嗯... 感觉我考的时候还是不太在状态..然后有的题目想出来了之后就不太想打了= =..然后四处duang啊duang..时间一下子就过去了呢>.< 根据C老