1e51e51e5 的数据显然是不可暴力枚举的。 我们用 s[r]−s[l−1]s[r]-s[l-1]s[r]−s[l−1] 表示 [l,r][l,r][l,r] 的区间和,看数据范围我们知道 s[i]s[i]s[i] 最多为 10610^6106, 也就是说我们要的平方和最多不超过 10310^3103,那样的话我们就可以试着枚举n以及平方和, 然后记录值等于 s[r]−j2s[r]−j^2s[r]−j2 的前缀和的个数即可得到答案。
#include <iostream>
#include <cstring>
#include <algorithm>
using namespace std;
typedef long long ll;
const int N = 1e5 + 10;
const int MAX = 1e5 * 10 + 10;
int cnt[MAX], s[N]; // cnt[]存储满足条件的区间出现的次数,s[]为前缀和数组
int main()
{
ll n, x, ans = 0;
cin >> n;
for(ll i = 1; i <= n; i ++){ // 初始化前缀和数组
cin >> x;
s[i] = s[i - 1] + x;
}
cnt[0] = 1;
for(ll i = 1; i <= n; i ++){
for(ll j = 0; j * j <= s[i]; j ++) // 从0到当前前缀和枚举完全平方数
ans += cnt[s[i] - j * j]; // 前缀和为s[i] - j * j的个数累加
cnt[s[i]] ++; // 更新当前前缀和出现的次数
}
cout << ans << endl;
return 0;
}
1010

被折叠的 条评论
为什么被折叠?



