Wannafly挑戰賽5 A.珂朵莉與宇宙
題目描述
星神是來自宇宙的
所以珂朵莉也是吧
所以我就出了個題
給你一個長爲n的序列a,有n*(n+1)/2個子區間,問這些子區間裏面和爲完全平方數的子區間個數
輸入描述:
第一行一個數n
第二行n個數表示序列a
輸出描述:
輸出一個數表示答案
示例1
輸入
6
0 1 0 9 1 0
#include<cstdio> using namespace std; int sum[100010]; int a[1000100]; int main () { int n; long long ans=0; scanf("%d",&n); for(int i=1;i<=n;i++){ scanf("%d",&sum[i]); sum[i]+=sum[i-1]; //a[sum[i]]++;先把a數組算出來是不對的 } /*分爲兩種情況: 1是第一個數是完全平方數 2是第一個數不是完全平方數 所以a[0]=1就是爲了處理第一種情況的 如果是第二種情況就沒必要讓a[0]=1了*/ a[0]=1; for(int i=1;i<=n;i++){ for(int j=0;j*j<=sum[i];j++){ ans+=a[sum[i]-j*j]; } //a[sum[i]]++表示某個前綴和出現的次數,且不能先把a數組給算出來, a[sum[i]]++; } printf("%lld\n", ans); return 0; }
前綴和a[j]肯定是大於等於可能滿足的平方數的,所以前面用求得的n個前綴和 依次去 減去 一個平方數 得到的數 就是要截去的數目(也即一個前綴和),因爲區間是連續的,所以只能是減掉某一個前綴和,所以就轉化成求某些前綴和的總個數了
由題意也可得:sum[m] - sum[n] = j * j ,並且 m>=n
j 就是那個平方數 ,並且 j 在 閉區間[n,m] 內。由此可以看出求 j 的個數 就等價於就 sum[n] 的個數了 ( 有點逆向思維的味道)