训练赛1-3:珂朵莉与宇宙
题目描述
星神是来自宇宙的
所以珂朵莉也是吧
所以我就出了个题
给你一个长为n的序列a,有n*(n+1)/2个子区间,问这些子区间里面和为完全平方数的子区间个数
输入格式:
第一行一个数n
第二行n个数表示序列a
输出格式:
输出一个数表示答案
输入样例:
6
0 1 0 9 1 0
输出样例
11
备注:
1 <= n <= 100000
0 <= ai <= 10
思路:
°求某个区间的和,自然要想到前缀和知识。
°由于1 <= n <= 100000 ,在循环遍历时可能会出现数据溢出的情况, 所以把数据类型定义为long long。
°根据公式 sum[R] - sum[L-1] = j * j ,区间[L~R]的和等于一个完全平方数,所以移项 sum[L-1] = sum[R] - j * j,此时只需要查找sum[L-1]出现多少次就可以了,出现的次数用cnt[]来存放。
°cnt[0] = 1的意思是 假如cnt[0]是一个完全平方数,就初始化为1。
AC代码:
点击查看代码
#include<iostream>
using namespace std;
typedef long long LL;
const int maxN = 1e5+10;
LL a[maxN],sum[maxN];
int n,cnt[maxN*10];
int main(){
scanf("%d",&n);
for(int i = 1;i<=n;i++) {
scanf("%d",&a[i]);
//前缀和的计算
sum[i] = sum[i-1]+a[i];
}
LL ans = 0;
cnt[0] = 1;//如果M[0]是完全平方数就加进去
for(int R = 1;R<=n;R++){
for(int x = 0;x * x <= sum[R];x++){
ans += cnt[sum[R] - x *x]; // sum[R] - sum[L-1] = j * j;
}
cnt[sum[R]]++;
}
printf("%d\n",ans);
return 0;
}

浙公网安备 33010602011771号