abc480E Product-Bounded Arithmetic Sequences
用了一点动态规划的思想来考虑这个问题,也就是想清楚哪些信息必须枚举那些信息适合用来统计答案~
目前做过的最简单的一道 e 题。
考虑生成一个合法序列 \(A\) 需要知道的信息:开头,长度,公差,乘积。
考虑怎么统计答案。考虑枚举开头和长度,然后求解公差的范围。算一下发现枚举开头最多 \(10^6\),长度的衰减其实也很快,基本是对数级别的,公差也可以通过二分在常数时间内确定,因此这样统计是可行的。
#include<bits/stdc++.h>
//#include<atcoder/all>
#define F(i,l,r) for(int i(l); i <= (r); ++ i)
#define G(i,r,l) for(int i(r); i >= (l); -- i)
#define mp make_pair
#define fi first
#define se second
#define pii pair<int, int>
using namespace std;
//using namespace atcoder;
using ll = long long;
const int N = 1000;
const int mod = 1e9 + 7;
int a[N];
ll n;
bool check(ll nw, int l, int x){
ll ret = 1;
F(i, 1, l){
if(ret > n / nw) return 0;
ret *= nw;
nw += x;
}
return 1;
}
void Main(){
cin >> n;
int maxi = 1000000;
F(i, 1, 1000000){
if(1ll * i * i * i > n){
maxi = i - 1;
break;
}
}
ll ans = 0;
F(i, 1, maxi){ // st
ll o = 1ll * i * (i + 1), p = i + 1;
F(j, 3, 20){ // length
++ p;
if(o > n / p) break;
o *= p;
int l = 0, r = 1e9 + 1, mid; // d
while(l + 1 < r){ // solve d
mid = (l + r) / 2;
if(check(i, j, mid)) l = mid;
else r = mid;
}
ans += l;
}
}
cout << ans << '\n';
return ;
}
signed main(){
ios::sync_with_stdio(0); cin.tie(0); cout.tie(0);
int T = 1;
while(T --) Main();
return fflush(0), 0;
}

浙公网安备 33010602011771号