E. Special Elements

  • Quiz
  • AC
  • 解説
    • editorialとは別解法
    • すべての範囲 l ~ r について和を求めて、作れるかをフラグで持っておく。和を求める高速化には累積和を使う
    • 累積和用に新たに配列を確保するとMLEするので、値の配列Aをそのまま上書きして累積和にする
    • 累積和の役目を終えた後はもとの配列Aに戻す逆操作をし、各aについてフラグを見ればいい
void solve(){
  ll N;
  cin>>N;
  VI A(N+1);
  rep(i, N){
    cin >> A[i+1];
  }
  rep(i,N){
    A[i+1] += A[i];
  }
  
  vector<bool> f(N*N+50);
  
  FOR(len,2,N+1){
    FOR(i,1,N-len+2){
      ll sum = A[i+len-1] - A[i-1];
      f[sum]=1;
    }
  }

  // 累積和もどし!
  for(int i=N; i>=1; i--){
    A[i] -= A[i-1];
  }

  ll cnt=0;
  FOR(i,1,N+1){
    ll a = A[i];
    if(f[a]){
      cnt++;
    }
  }
  p(cnt);
}

int main(){
    cin.tie(0);
    ios::sync_with_stdio(false);

    // input
    ll N; 
    cin>>N;
    
    while(N--)solve();
    
    return 0;
}