【BZOJ】【3930】【CQOI2015】选数
数论/莫比乌斯反演/快速mu前缀和
比较容易想到令f[x]表示gcd=x的方案数,令g[x]表示x|gcd的方案数。
那么有$ g(d)=\sum_{d|n} f(n)$,根据莫比乌斯反演,有$f(d)=\sum_{d|n} g(n)*\mu (\frac{n}{d})$
我一开始想的是算出g以后,倒序枚举 i ,然后枚举 i 的倍数,递推出所有的f[i]……
因为g比较好算嘛……快速幂一下什么的……
然而$10^9$直接吓傻我。
Orz PoPoQQQ
快速求出mu的前缀和,$10^9$也照样不虚,太神辣
- /**************************************************************
- Problem: 3930
- User: Tunix
- Language: C++
- Result: Accepted
- Time:4200 ms
- Memory:54024 kb
- ****************************************************************/
- //BZOJ 3930
- #include<cstdio>
- #include<map>
- #include<cstring>
- #include<cstdlib>
- #include<iostream>
- #include<algorithm>
- #define rep(i,n) for(int i=0;i<n;++i)
- #define F(i,j,n) for(int i=j;i<=n;++i)
- #define D(i,j,n) for(int i=j;i>=n;--i)
- #define pb push_back
- using namespace std;
- typedef long long LL;
- inline int getint(){
- int r=,v=; char ch=getchar();
- for(;!isdigit(ch);ch=getchar()) if (ch=='-') r=-;
- for(; isdigit(ch);ch=getchar()) v=v*-''+ch;
- return r*v;
- }
- const int N=1e7+,P=1e9+;
- const int INF=0x3f3f3f3f;
- /*******************template********************/
- int mu[N],prime[],tot;
- bool check[N];
- map<int,LL> mu_sum;
- LL n,d,l,r;
- void getmu(){
- int n=;
- mu[]=;
- F(i,,n){
- if (!check[i]){
- mu[i]=-;
- prime[++tot]=i;
- }
- F(j,,tot){
- int k=i*prime[j];
- if (k>n) break;
- check[k]=;
- if (i%prime[j]) mu[k]=-mu[i];
- else{
- mu[k]=;
- break;
- }
- }
- }
- F(i,,n) mu[i]+=mu[i-];
- }
- LL Mu_sum(int x){
- if (x<=) return mu[x];
- if (mu_sum.find(x)!=mu_sum.end())
- return mu_sum[x];
- LL i,last,re=;
- for(i=;i<=x;i=last+){
- last=x/(x/i);
- if (x/i-)
- re-=(Mu_sum(last)-Mu_sum(i-))*(x/i-);
- }
- return mu_sum[x]=re;
- }
- LL Pow(LL a,int b){
- LL r=;
- for(;b;b>>=,a=a*a%P) if (b&) r=r*a%P;
- return r;
- }
- LL solve(){
- LL i,last,re=;
- for(i=;i<=r;i=last+){
- last=min(r/(r/i),l/i?(l/(l/i)):INF);
- re+=(Mu_sum(last)-Mu_sum(i-))*Pow(r/i-l/i,n);
- re%=P;
- }
- return (re%P+P)%P;
- }
- int main(){
- #ifndef ONLINE_JUDGE
- freopen("3930.in","r",stdin);
- freopen("3930.out","w",stdout);
- #endif
- n=getint(); d=getint(); l=getint(); r=getint();
- l=(l-)/d; r=r/d;
- getmu();
- printf("%lld\n",solve());
- return ;
- }
然而$H-L \leq 10^5$并没用?不是的……我们可以枚举倍数!
Orz syk
记f[i]为gcd恰好为$K*i$的选数方案数,那么对于每一个$i$记$L$为$\lceil \frac{a}{K*i}\rceil $,$R$为$\lfloor\frac{b}{K*i}\rfloor$ 那么他的方案数就为$f[i] = (R-L+1) ^ N - (R-L+1)-\sum_{a=1,2,\dots} f[a*i]$最后的f[1]即为答案。注意若$\lceil \frac{a}{K} \rceil == 1$ 那么全部选K也是一种方案,需要+1。
(话说好不容易想到一次莫比乌斯反演,然而却做不出来……唉
- /**************************************************************
- Problem: 3930
- User: Tunix
- Language: C++
- Result: Accepted
- Time:412 ms
- Memory:1664 kb
- ****************************************************************/
- //BZOJ 3930
- #include<cstdio>
- #include<cstring>
- #include<cstdlib>
- #include<iostream>
- #include<algorithm>
- #define rep(i,n) for(int i=0;i<n;++i)
- #define F(i,j,n) for(int i=j;i<=n;++i)
- #define D(i,j,n) for(int i=j;i>=n;--i)
- #define pb push_back
- using namespace std;
- typedef long long LL;
- inline int getint(){
- int r=,v=; char ch=getchar();
- for(;!isdigit(ch);ch=getchar()) if (ch=='-') r=-;
- for(; isdigit(ch);ch=getchar()) v=v*-''+ch;
- return r*v;
- }
- const int N=1e5+,P=1e9+;
- /*******************template********************/
- int d[N],n,K,l,r,a,b;
- int Pow(int a,int b){
- int r=;
- for(;b;b>>=,a=(LL)a*a%P) if (b&) r=(LL)r*a%P;
- return r;
- }
- int main(){
- #ifndef ONLINE_JUDGE
- freopen("3930.in","r",stdin);
- freopen("3930.out","w",stdout);
- #endif
- n=getint(); K=getint(); a=getint(); b=getint();
- l=a/K; r=b/K;
- if (a%K) l++;
- D(i,,){
- int R=r/i,L=l/i;
- if (l%i) L++;
- if (l<=r){
- d[i]=Pow(R-L+,n);
- d[i]=(d[i]-(R-L+)+P)%P;
- for(int j=i+i;j<=;j+=i) d[i]=(d[i]-d[j]+P)%P;
- }
- }
- if (l==) d[]=(d[]+)%P;
- printf("%d\n",d[]);
- return ;
- }
3930: [CQOI2015]选数
Time Limit: 10 Sec Memory Limit: 512 MB
Submit: 434 Solved: 222
[Submit][Status][Discuss]
Description
我
们知道,从区间[L,H](L和H为整数)中选取N个整数,总共有(H-L+1)^N种方案。小z很好奇这样选出的数的最大公约数的规律,他决定对每种方
案选出的N个整数都求一次最大公约数,以便进一步研究。然而他很快发现工作量太大了,于是向你寻求帮助。你的任务很简单,小z会告诉你一个整数K,你需要
回答他最大公约数刚好为K的选取方案有多少个。由于方案数较大,你只需要输出其除以1000000007的余数即可。
Input
输入一行,包含4个空格分开的正整数,依次为N,K,L和H。
Output
输出一个整数,为所求方案数。
Sample Input
Sample Output
HINT
样例解释
Source
【BZOJ】【3930】【CQOI2015】选数的更多相关文章
- BZOJ 3930: [CQOI2015]选数 递推
3930: [CQOI2015]选数 Time Limit: 20 Sec Memory Limit: 256 MB 题目连接 http://www.lydsy.com/JudgeOnline/pro ...
- 【刷题】BZOJ 3930 [CQOI2015]选数
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个整数都求一次最大公 ...
- BZOJ 3930: [CQOI2015]选数 莫比乌斯反演
https://www.lydsy.com/JudgeOnline/problem.php?id=3930 https://blog.csdn.net/ws_yzy/article/details/5 ...
- 【递推】BZOJ 3930: [CQOI2015]选数
Description 我们知道,从区间[L,H](L和H为整数)中选取N个整数,总共有(H-L+1)^N种方案.小z很好奇这样选出的数的最大公约数的规律,他决定对每种方案选出的N个整数都求一次最大公 ...
- bzoj 3930: [CQOI2015]选数【快速幂+容斥】
参考:https://www.cnblogs.com/iwtwiioi/p/4986316.html 注意区间长度为1e5级别. 则假设n个数不全相同,那么他们的gcd小于最大数-最小数,证明:则gc ...
- bzoj 3930: [CQOI2015]选数【递推】
妙啊 这个题一上来就想的是莫比乌斯反演: \[ f(d)=\sum_{k=1}^{\left \lceil \frac{r}{d} \right \rceil}\mu(k)(\left \lceil ...
- BZOJ 3930: [CQOI2015]选数 莫比乌斯反演 + 杜教筛
求 $\sum_{i=L}^{R}\sum_{i'=L}^{R}....[gcd_{i=1}^{n}(i)==k]$ $\Rightarrow \sum_{i=\frac{L}{k}}^{\fra ...
- 【BZOJ】3930: [CQOI2015]选数
题意 从区间\([L, R]\)选\(N\)个数(可以重复),问这\(N\)个数的最大公约数是\(K\)的方案数.(\(1 \le N, K \le 10^9, 1 \le L \le R \le 1 ...
- 3930: [CQOI2015]选数
Time Limit: 10 Sec Memory Limit: 512 MBSubmit: 1958 Solved: 979[Submit][Status][Discuss] Descripti ...
随机推荐
- Android 前台服务
Android 前台服务 学习自 https://blog.csdn.net/guolin_blog/article/details/11952435#t3 前台服务漫谈 我们之前学习的Service ...
- python文件相关操作
Python文件相关操作 打开文件 打开文件,采用open方法,会将文件的句柄返回,如下: f = open('test_file.txt','r',encoding='utf-8') 在上面的代码中 ...
- Ubuntu 16.04 安装WPS
1.下载安装包和缺少的字体 安装包下载[http://wps-community.org/download.html?vl=a21#download](这里下载的是最新的安装包) 缺少的字体下载[链接 ...
- Regex.Split
private static List<int> GetThemeIds(string themeList) { const string split = "!===!" ...
- 三星打印机SCX-4824HN全套驱动(打印/扫描)
链接: https://pan.baidu.com/s/1EUXsti4niHlYcMHMJqqnXA 密码: r91a
- LPC18xx/43xx OTP Controller driver
LPC18xx/43xx OTP Controller driver /* * @brief LPC18xx/43xx OTP Controller driver * * @note * Copyri ...
- HOWTO: Use STM32 SPI half duplex mode
HOWTO: Use STM32 SPI half duplex mode I’ve got my hands onto some STM32F030F4P6 ARM-Cortex M0 proces ...
- STM32F4: Generating parallel signals with the FSMC
STM32F4: Generating parallel signals with the FSMC The goal: The memory controller can be used to ge ...
- 【Go命令教程】4. go get
hc@ubt:~$ go get github.com/hyper-carrot/go_lib/logging 命令 go get 可以根据要求和实际情况从互联网上下载或更新指定的代码包及其依赖包,并 ...
- Ubuntu使用安装或者卸载软件!!!
安装软件: 1.在应用商店里面下载安装 2.在终端sudo apt-get install 软件名 3.使用ppa:加入一个ppa源:sudo add-apt-repository ppa:user/ ...