CF1561D Up the Strip
Up the Strip
题意
你现在在 \(n\) 号格子,你需要跳到 \(1\) 号格子,你可以有两种跳法:
- 你可以做减法,即选择一个数 \(k\in [1,n)\) ,从 \(n\) 跳到 \(n-k\)
- 你可以做除法,即选择一个数 \(k\in(1,n]\),从 \(n\) 跳到 \(\lfloor\frac{n}{k}\rfloor\)
问你有多少种跳法,答案对给定模数取模。
题解
经典 \(dp\)。
很容易想到对做减法的部分求前缀和,对做除法的部分做整除分块。然而分块的复杂度是 \(\sqrt{n}\) 级别的,过不了 \(D2\) , 于是考虑优化。前缀和部分不能优化不了了,现优化整除分块。
经典套路:普通复杂度做法做不了就考虑算贡献。我们现在想知道,对于一个数 \(n\) ,他在除以 \(k\in(1,n]\) 里的数时,除出来的数分别出现了多少次。例如 \(10\) ,
| 9 | 8 | 7 | 6 | 5 | 4 | 3 | 2 | 10 |
|---|---|---|---|---|---|---|---|---|
| 1 | 1 | 1 | 1 | 2 | 2 | 3 | 5 | 1 |
可以看到 \(1\) 出现了五次, \(2\) 出现了两次,\(3,5\) 分别出现了一次。我尝试用公式来表达,对于一个数 \(i\) ,他出现的次数为 \(\frac{n}{i}-\frac{n}{i+1}\)(易证)。于是 \(dp\) 的式子就可以写成
\]
第一部分可以用前缀和优化掉,第二部分怎么优化呢?单独考察 \(f_i\times \lfloor \frac{n}{i} \rfloor\) , 可以知道 \(n\) 只有在 \(i,2i,3i,...\) 的时候才会发生变化,于是我们考虑差分,开个数组 \(g\) 来存这个差分,更新到 \(f_i\) 时,我们就把 \(g_i,g_{2i},...\) 更新了。\(f_i\times \lfloor \frac{n}{i+1}\rfloor\) 同理。
AC代码
#include <bits/stdc++.h>
#define IO ios::sync_with_stdio(NULL)
#define sc(z) scanf("%lld", &(z))
#define _ff(i, a, b) for (int i = a; i <= b; ++i)
#define _rr(i, a, b) for (int i = b; i >= a; --i)
#define _f(i, a, b) for (int i = a; i < b; ++i)
#define _r(i, a, b) for (int i = b - 1; i >= a; --i)
#define mkp make_pair
#define endl "\n"
#define pii pair<int,int>
#define fi first
#define se second
#define lowbit(x) x&(-x)
#define pb push_back
using namespace std;
typedef double db;
typedef long long ll;
typedef long double ld;
const int N = 4e6 + 5;
const ll M = 1e5 + 5;
const ll mod = 998244353;
const int inf = 1e9;
const double eps = 1e-9;
const double PI = acos(-1.0);
const pii NIL = {0,0};
ll f[N],g[N];
void solve() {
ll sum=0,sum2=0;f[1]=1;
ll n,p;cin>>n>>p;
_ff(i,1,n){
f[i]=(f[i]+((sum+sum2)%p+g[i])%p)%p;
for(int j=i;j<=n;j+=i)g[j]=(g[j]+f[i])%p;
for(int j=i+1;j<=n;j+=i+1)g[j]=(g[j]-f[i]+p)%p;
sum=(sum+f[i])%p;
sum2=(sum2+g[i])%p;
}
cout<<f[n]<<endl;
}
int main() {
IO;
#ifndef ONLINE_JUDGE
freopen("input.txt", "r", stdin);
freopen("output.txt", "w", stdout);
#endif // !ONLINE_JUDGE
// ll T; cin>>T;
// _f(i,0,T) {
// // cout<<"Case "<<i+1<<": ";
// solve();
// }
solve();
return 0;
}
CF1561D Up the Strip的更多相关文章
- python strip()函数 介绍
python strip()函数 介绍,需要的朋友可以参考一下 函数原型 声明:s为字符串,rm为要删除的字符序列 s.strip(rm) 删除s字符串中开头.结尾处,位于 rm删除 ...
- 4、Python:strip(),split()
1.strip()函数 strip()是删除'()'里面的字符,当()为空时,默认删除空白符(包括'\n','\r','\t','') (1)s.strip(rm) 删除s字符串中开头. ...
- Strip JS – 低侵入,响应式的 Lightbox 效果
Strip 是一个灯箱效果插件,显示的时候只会覆盖部分的页面,这使得侵扰程度较低,并留出了空间与页面上的大屏幕,同时给予小型移动设备上的经典灯箱体验.Strp JS 基于 jQuery 库实现,支持 ...
- strip的用法
函数原型 声明:s为字符串,rm为要删除的字符序列 s.strip(rm) 删除s字符串中开头.结尾处,位于 rm删除序列的字符 s.lstrip(rm) 删除s字符串中开头 ...
- python中strip,lstrip,rstrip简介
一.起因 今天在做角色控制中,有一个地方用到rstrip,判断用户请求的url是否与数据库对应可用权限中url相符. if request.path == x.url or request.path. ...
- 【C++实现python字符串函数库】strip、lstrip、rstrip方法
[C++实现python字符串函数库]strip.lstrip.rstrip方法 这三个方法用于删除字符串首尾处指定的字符,默认删除空白符(包括'\n', '\r', '\t', ' '). s.st ...
- pythong中字符串strip的用法
strip的用法是去除字符串中前后两端的xx字符,xx是一个字符数组,并不是去掉“”中的字符串, 数组中包含的字符都要在字符串中去除.默认去掉空格,lstrip则是去掉左边的,rstrip是右边的 见 ...
- Python strip函数用法小结
声明:s为字符串,rm为要删除的字符序列 s.strip(rm) 删除s字符串中开头.结尾处,位于 rm删除序列的字符 s.lstrip(rm) 删除s字符串中开头处,位于 ...
- python strip() lstrip() rstrip() 使用方法
Python中的strip用于去除字符串的首尾字符串,同理,lstrip用于去除最左边的字符,rstrip用于去除最右边的字符. 这三个函数都可传入一个参数,指定要去除的首尾字符. 需要注意的是,传入 ...
- Linux Strip
一.简介 strip经常用来去除目标文件中的一些符号表.调试符号表信息,以减小程序的大小. 二.语法 https://sourceware.org/binutils/docs/binutils/str ...
随机推荐
- DFS略思维题做题记录
洛谷:P4399 [JSOI2008]Blue Mary的职员分配 链接 代码: #include<iostream> using namespace std; int n,x,y,z,A ...
- Java Maven环境搭建
下载 Maven 官网地址: https://maven.apache.org/ 点击左侧的 "Download" 下载 Files 下面的 zip 文件 推荐使用迅雷进行下载,速 ...
- Visio中的图无失真导入LaTeX中
参考网址: LaTeX导入图片不失帧的方法_奋斗的西瓜瓜的博客-CSDN博客_latex图片模糊 LaTeX中插入eps格式图片_不觉岁华成暗度的博客-CSDN博客_eps latex Visio图片 ...
- 2023 01 19 HW
2023 01 19 HW Okay, then let's start. Okay. Maybe Karina, we start with the C2 design freeze. Yeah, ...
- python36
无限循环 如果条件判断语句永远为 true,循环将会无限的执行下去,如下实例: 实例 #!/usr/bin/python # -*- coding: UTF-8 -*- var = 1 while v ...
- 01java大数据开发_Linux安装
大数据开发01--linux环境安装配置 1.1软件包和资料 需要安装:VMware.CentOs6.5.Xfth5.Xshell5.Xmind: 需要可加V:zhanjiquan666: 安装注意点 ...
- 日常开发记录-Object函数的内置方法Object.entries
方法1: const data = { id: 1, name: "张三", age: 22 } let params = "" /* Object.entri ...
- Windows打开回收站的几种方式
1. 桌面双击回收站图标打开回收站,简单.快捷.方便,但在打开多个窗口时候还要最小化这些窗口以显示桌面,如果还要迅速恢复这些窗口的话也算是麻烦 2. 磁盘每个分区根目录下都有一个名称为$Recycle ...
- python setup.py install 安装、删除。
# python install 安装.卸载 python setup.py install --record files.txt cat files.txt | xargs rm -rf
- Android Studio打开现有的项目,Android自带的类、函数(方法)属性等爆红,含解决方式
如上图,Android 自带的 setContentView 爆红,XML文件内 android:相关的属性(如android:layout_width) 爆红 原因: 使用Android Studi ...