当前位置: 首页 > news >正文

【题解】P3172 [CQOI2015] 选数(倍数莫反做法)

题面:从 [L,H] 选 N 个数(可能重复),一共有 (H-L+1)^N 种取法。问这些取法中满足 N 个数最大公约数为 K 的有多少种。

第一眼就知道要把 L=\left \lfloor \frac{L}{K} \right \rfloor+[L\,mod\,K\neq 0]H=\left \lfloor \frac{H}{K} \right \rfloor

然后问题就变成求满足 N 个数最大公约数为 1 有多少种

 直接来解,复习下莫反公式 :

倍数形式:F(n)=\sum_{n|d}^{}f(d) \Rightarrow f(n) = \sum_{n|d}^{}\mu (\frac{d}{n})F(d),不会点这里

考虑构造 F(n)=\sum_{n|d}^{}f(d),结合题目则有两个函数的定义:

F(n):从 [L,H] 中选 N 个数的最大公约数是 n 或者 n倍数的情况数。

f(n):从 [L,H] 中选 N 个数的最大公约数是 n 的情况数。

那么就有:f(n)=\sum_{n|d}^{}\mu (\frac{d}{n})F(d)

我们只需要最大公约数为 1 的情况,所以:

f(1)=\sum_{d=1}^{H}\mu (d)F(d)

(其实这里的 d 严格意义上是无限大的,但本题最大值只能取到 H

现在我们来看看怎么求 F(d)

回顾定义,发现应该是:(\left \lfloor \frac{H}{d} \right \rfloor-(\left \lfloor \frac{L}{d} \right \rfloor+[L\,mod\,d\neq 0])+1)^N

很好,差一点就能分块加速了。。

其实我们可以让 L-1,这样直接 (\left \lfloor \frac{H}{d} \right \rfloor-\left \lfloor \frac{L-1}{d} \right \rfloor)^N

(当 n=1 的情况也符合,大家可以自己试下)

那最后就变成了:f(1)=\sum_{d=1}^{H}\mu (d)(\left \lfloor \frac{H}{d} \right \rfloor-\left \lfloor \frac{L-1}{d} \right \rfloor)^N

代码:

#include<bits/stdc++.h>
using namespace std;
template<typename T> void qread(T &x){x=0; int f=1; char c=getchar();for(; !isdigit(c); c=getchar()) if(c=='-') f=-1;for(; isdigit(c); c=getchar()) x=x*10+(c-'0');x*=f;
}
typedef long long LL;
const int N=5e6+10;
const LL P=1e9+7;
int pr, prime[N];
LL mu[N];
bool v[N]; 
void init(){pr=0; memset(v, 0, sizeof(v));mu[1]=1; mu[0]=0;for(int i=2; i<=N-10; i++){if(!v[i]){pr++; prime[pr]=i;mu[i]=-1;} for(int j=1; (j<=pr) && (i*prime[j]<=N-10); j++){int p=prime[j];v[i*p]=1;if(i%p==0){mu[i*p]=0;break;}else mu[i*p]=-mu[i]; }}for(int i=1; i<=N-10; i++) mu[i]+=mu[i-1];
}
LL q_pow(LL a, LL b){LL res=1;while(b){if(b&1) res=res*a%P;a=a*a%P; b/=2;}return res;
}
LL n, K, L, H;
map<LL, LL> hsm;
LL calc(LL x){if(x<=N-10) return mu[x];if(hsm.find(x)!=hsm.end()) return hsm[x];LL res=1;for(int i=2, j; i<=x; i=j+1){j=x/(x/i);res=(res-calc(x/i)*(j-i+1)%P+P)%P;}return hsm[x]=res;
}
LL solve(){LL res=0; L--;for(int i=1, j; i<=H; i=j+1){if(!(L/i)) j=H/(H/i); //到了一定位置大家的 L/i都变成 0,没有参考价值了 else j=min(L/(L/i), H/(H/i));res=(res+q_pow(H/i-L/i, n)*((calc(j)-calc(i-1))%P+P)%P)%P;}return res;
}
int main(){init();qread(n); qread(K); qread(L); qread(H);H=H/K; L=((L%K==0)? L=L/K: L=L/K+1);printf("%lld\n", solve());return 0;
}

http://www.dtcms.com/a/316190.html

相关文章:

  • 深圳多奥500KG磁力锁(DAIC-MJ-500S)技术解析与产品优势报告,应用到门禁系统坚若磐石!
  • 计算机网络 第2章通信基础(竟成)
  • Pycaita二次开发基础代码解析:参数化模板创建与设计表驱动建模
  • 【Java面试题】注解,异常相关知识
  • Go语言的gRPC教程-错误处理
  • Android AppSearch 深度解析:现代应用搜索架构与实践
  • Elasticsearch向量库
  • 【web应用】前后端分离项目基本框架组成:Vue + Spring Boot 最佳实践指南
  • 深度解析 TCP 三次握手与四次挥手:从原理到 HTTP/HTTPS 的应用
  • 微服务—OpenFeign
  • Spring中七种Propagation类的事务属性详解
  • 研发团队看板协作中的自动化实践:集成CI/CD与任务流转
  • 007TG洞察:高效运营Telegram私域流量:技术挑战与自动化解决方案探索
  • 中科米堆CASAIM自动化三维扫描系统自动测量压铸件尺寸
  • 【原创】基于gemini-2.5-flash-preview-05-20多模态模型实现短视频的自动化二创
  • 从 “看懂图” 到 “读懂视频”:多模态技术如何用文本反哺视觉?
  • 原型模式在C++中的实现与面向对象设计原则
  • 二维数点问题 1
  • 学习日志28 python
  • AI编程新时代:从氛围编程到上下文编程的深度实践和思考
  • 鸿蒙开发、大数据开发、Java开发与前端开发全面对比解析
  • 【银行测试】银行票据项目业务+票据测试点分析(四)
  • 2025《艾诺提亚失落之歌》逆向工程解包尝试
  • Linux网络编程:TCP初体验
  • VirtualBox安装教程
  • 64位程序调用32位dll方法
  • 【Linux系统编程】线程概念与控制
  • 使用valgrind工具检测server端lib库的内存泄漏
  • FT5X06 触摸芯片
  • 【技术教程】如何将 ONLYOFFICE 文档连接到 Confluence