Codeforces Round #740 (Div. 2) D1. Up the Strip (simplified version)
Posted yueshehanjiang
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Codeforces Round #740 (Div. 2) D1. Up the Strip (simplified version)相关的知识,希望对你有一定的参考价值。
D1. Up the Strip (simplified version)
题意:
你现在在n
你可以n - x [ 1 <= x <= n - 1 ]
你也可以 n / x [ 2 <= x <= n ]
问你从n到1的方案数对m取模
2 ≤ n ≤ 2e5 1e8 < m < 1e9
思路:
首先
大致方向先确定
是动态规划
然后先把暴力的n^2的代码写出来
写出来之后在考虑优化
假设f[i]
表示从第i层到第1层的方案数
转移方程题目已经给你了
先看下面暴力的代码
#include<bits/stdc++.h>
#define fer(i,a,b) for(re i = a ; i <= b ; ++ i)
#define der(i,a,b) for(re i = a ; i >= b ; -- i)
#define re register int
#define pll pair<int,int>
#define pb push_back
#define x first
#define y second
#define sf(x) scanf("%d",&x)
#define sfl(x) scanf("%lld",&x)
#define de(x) cout << x << "\\n" ;
typedef long long ll ;
using namespace std;
const int N = 1e6 + 10 , M = 2010 , inf = 0x3f3f3f3f , mod = 1e9 + 7 ;
ll f[N] ;
ll n , p ;
int main()
{
cin >> n >> p ;
f[1] = 1 ;
for(int i = 2 ; i <= n ; i ++)
{
for(int j = 1 ; j < i ; j ++)
{
f[i] = (f[i] + f[j]) % p ;
}
for(int j = 2 ; j <= i ; j ++)
{
f[i] = (f[i] + f[i/j]) % p ;
}
}
cout << f[n] << "\\n" ;
return 0;
}
时间复杂度 o n^2
肯定过不去
考虑一下第一层循环怎么优化
for(int j = 1 ; j < i ; j ++)
{
f[i] = (f[i] + f[j]) % p ;
}
用res表示f[k] [1 <= k < i] 的前缀和
o1转移即可
在考虑一下第二层的优化
for(int j = 2 ; j <= i ; j ++)
{
f[i] = (f[i] + f[i/j]) % p ;
}
简化一下就是
f[i/2] + f[i/3] + f[i/4] + ....... + f[i/i]
考虑在加一项
f[i/1]
就变成了
f[i/1] + f[i/2] + f[i/3] + f[i/4] + ....... + f[i/i] - f[i/1]
下面这个式子是整除分块
f[i/1] + f[i/2] + f[i/3] + f[i/4] + ....... + f[i/i]
可以nsqrtn求出来
在减去f[i/1]即可
整除分块
时间复杂度:O nsqrtn
#include<bits/stdc++.h>
#define fer(i,a,b) for(re i = a ; i <= b ; ++ i)
#define der(i,a,b) for(re i = a ; i >= b ; -- i)
#define re register int
#define pll pair<int,int>
#define pb push_back
#define x first
#define y second
#define sf(x) scanf("%d",&x)
#define sfl(x) scanf("%lld",&x)
#define de(x) cout << x << "\\n" ;
typedef long long ll ;
using namespace std;
const int N = 1e6 + 10 , M = 2010 , inf = 0x3f3f3f3f , mod = 1e9 + 7 ;
ll f[N] ;
ll n , p ;
int main()
{
cin >> n >> p ;
f[1] = 1 ;
ll cnt = 0 ;
ll res = f[1] ;
for(int i = 2 ; i <= n ; i ++)
{
f[i] = (f[i] + res) % p ;
ll x = f[i] ;
cnt = 0 ;
for(int l = 1 , r ; l <= i ; l = r + 1)
{
r = i / (i / l) ;
cnt = (cnt % p + (r - l + 1) * f[i/l] % p) % p;
}
f[i] = (f[i] + cnt - x) % p ;
// for(int j = 2 ; j <= i ; j ++)
// {
// f[i] = (f[i] + f[i/j]) % p ;
// }
res = (res + f[i]) % p ;
}
cout << f[n] << "\\n" ;
return 0;
}
d2变大了n的范围
前缀和可以on
主要是整除分块的 nsqrtn 大概是1e10的时间复杂度
所以过不去
进一步考虑优化
缩进优化(整除分块)
时间复杂度nlogn
目前还不会
待补
以上是关于Codeforces Round #740 (Div. 2) D1. Up the Strip (simplified version)的主要内容,如果未能解决你的问题,请参考以下文章
Codeforces Round #740 Div. 2 A B C D1 D2
Codeforces Round #740 Div. 2 A B C D1 D2
Codeforces Round #740 (Div. 2) D1. Up the Strip (simplified version)
Codeforces Round #740 (Div. 2) D1. Up the Strip (simplified version)
Codeforces Round #740 (Div. 2, based on VK Cup 2021 - Final (Engine))
Codeforces Round #740 (Div. 2, based on VK Cup 2021 - Final (Engine))ABCD1D2E题解