数论/莫比乌斯反演/快速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

2 2 2 4

Sample Output

3

HINT

样例解释

所有可能的选择方案:(2, 2), (2, 3), (2, 4), (3, 2), (3, 3), (3, 4), (4, 2), (4, 3), (4, 4)
其中最大公约数等于2的只有3组:(2, 2), (2, 4), (4, 2)
对于100%的数据,1≤N,K≤10^9,1≤L≤H≤10^9,H-L≤10^5

Source

[Submit][Status][Discuss]

【BZOJ】【3930】【CQOI2015】选数的更多相关文章

  1. BZOJ 3930: [CQOI2015]选数 递推

    3930: [CQOI2015]选数 Time Limit: 20 Sec Memory Limit: 256 MB 题目连接 http://www.lydsy.com/JudgeOnline/pro ...

  2. 【刷题】BZOJ 3930 [CQOI2015]选数

    Description 我们知道,从区间[L,H](L和H为整数)中选取N个整数,总共有(H-L+1)^N种方案.小z很好奇这样选出的数的最大公约数的规律,他决定对每种方案选出的N个整数都求一次最大公 ...

  3. bzoj 3930: [CQOI2015]选数

    Description 我们知道,从区间[L,H](L和H为整数)中选取N个整数,总共有(H-L+1)^N种方案.小z很好奇这样选出的数的最大公约数的规律,他决定对每种方案选出的N个整数都求一次最大公 ...

  4. BZOJ 3930: [CQOI2015]选数 莫比乌斯反演

    https://www.lydsy.com/JudgeOnline/problem.php?id=3930 https://blog.csdn.net/ws_yzy/article/details/5 ...

  5. 【递推】BZOJ 3930: [CQOI2015]选数

    Description 我们知道,从区间[L,H](L和H为整数)中选取N个整数,总共有(H-L+1)^N种方案.小z很好奇这样选出的数的最大公约数的规律,他决定对每种方案选出的N个整数都求一次最大公 ...

  6. bzoj 3930: [CQOI2015]选数【快速幂+容斥】

    参考:https://www.cnblogs.com/iwtwiioi/p/4986316.html 注意区间长度为1e5级别. 则假设n个数不全相同,那么他们的gcd小于最大数-最小数,证明:则gc ...

  7. bzoj 3930: [CQOI2015]选数【递推】

    妙啊 这个题一上来就想的是莫比乌斯反演: \[ f(d)=\sum_{k=1}^{\left \lceil \frac{r}{d} \right \rceil}\mu(k)(\left \lceil ...

  8. BZOJ 3930: [CQOI2015]选数 莫比乌斯反演 + 杜教筛

    求 $\sum_{i=L}^{R}\sum_{i'=L}^{R}....[gcd_{i=1}^{n}(i)==k]$   $\Rightarrow \sum_{i=\frac{L}{k}}^{\fra ...

  9. 【BZOJ】3930: [CQOI2015]选数

    题意 从区间\([L, R]\)选\(N\)个数(可以重复),问这\(N\)个数的最大公约数是\(K\)的方案数.(\(1 \le N, K \le 10^9, 1 \le L \le R \le 1 ...

  10. 3930: [CQOI2015]选数

    Time Limit: 10 Sec  Memory Limit: 512 MBSubmit: 1958  Solved: 979[Submit][Status][Discuss] Descripti ...

随机推荐

  1. ajax和302(转)

    原文:http://www.cnblogs.com/dudu/p/ajax_302_found.html 在ajax请求中,如果服务器端的响应是302 Found,在ajax的回调函数中能够获取这个状 ...

  2. Android `AsyncTask`简要分析

    AsyncTask简要分析 经典异步任务:AsyncTask,使用场景有:批量下载,批量拷贝等.官方文档就直接给出了一个批量下载的示例. private class DownloadFilesTask ...

  3. UVA.11427.Expect the Expected(期望)

    题目链接 \(Description\) https://blog.csdn.net/Yukizzz/article/details/52084528 \(Solution\) 首先每一天之间是独立的 ...

  4. hdu 1754 I Hate It(树状数组区间求最值)2007省赛集训队练习赛(6)_linle专场

    题意: 输入一行数字,查询第i个数到第j个数之间的最大值.可以修改其中的某个数的值. 输入: 包含多组输入数据. 每组输入首行两个整数n,m.表示共有n个数,m次操作. 接下来一行包含n个整数. 接下 ...

  5. 开源的在线评测系统——Vakuum

    项目地址 http://code.google.com/p/vakuum-oj/ https://github.com/BYVoid/vakuum 简介 Vakuum是一个基于Linux+PHP的在线 ...

  6. spring boot 集成 druid

    写在前面 因为在用到spring boot + mybatis的项目时候,经常发生访问接口卡,服务器项目用了几天就很卡的甚至不能访问的情况,而我们的项目和数据库都是好了,考虑到可能是数据库连接的问题, ...

  7. 微信小程序开发需要注意的29个坑

    1.小程序名称可以由中文.数字.英文.长度在3-20个字符之间,一个中文字等于2个字符. 2.小程序名称不得与公众平台已有的订阅号.服务号重复.如提示重名,请更换名称进行设置. 3.小程序名称在帐号信 ...

  8. HTML5定稿了,终于有一种编程语言开发的程序可以在Android和IOS两种设备上运行了

    2007 年 W3C (万维网联盟)立项 HTML5,直至 2014 年 10 月底,这个长达八年的规范终于正式封稿. 过去这些年,HTML5 颠覆了 PC 互联网的格局,优化了移动互联网的体验,接下 ...

  9. RDMA over TCP的协议栈工作过程浅析

    http://blog.chinaunix.net/uid-140205-id-2849342.html

  10. 液晶电视插有线电视信号线的是哪个接口 HDMI是什么接口

    1.液晶电视插有线电视信号线的接口(模拟信号)是射频接口(也叫RF接口,同轴电缆接口,闭路线接口),数字信号就得通过机顶盒转换成模拟信号视频输出至电视,才能正常收看电视节目. 2.电视机或高清机顶盒上 ...