abc480E Product-Bounded Arithmetic Sequences

abc480E

用了一点动态规划的思想来考虑这个问题,也就是想清楚哪些信息必须枚举那些信息适合用来统计答案~

目前做过的最简单的一道 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;
}
posted @ 2026-10-18 01:14  superl61  阅读(13)  评论(0)    收藏  举报