ABC177に参加してみた
初めに
ABC177はAB完でした。C問題はほぼほぼ解けていたんですが
問題文を読み間違えている事に最後まで気づかず回答できませんでしたorz
はい、ということで今回はC問題について書いていきます。。。
https://atcoder.jp/contests/abc177
※ブログ内で問題の制約事項をすべて記載はしないので、制約事項は↑のURLより参照願います。
C - Sum of product of pairs
N個の整数が与えられるのでを満たす
すべてのについてのの和をで割った数を求める問題です。
解説を見てからの回答
#include<bits/stdc++.h> using namespace std; using ll = long long; const long long INF = 1LL<<60; typedef pair<ll,ll> Pair; int main(){ ll N; ll ans = 0; ll mod = 1e9 + 7; cin >> N; vector<ll> A(N); vector<ll> S(N + 1); for (ll i = 0; i < N;++i) cin >> A[i]; S[0] = 0; for (ll i = 0; i <N;++i){ // 累積和を求める S[i+1] = (S[i] + A[i]); } for (ll i = 0; i < N;++i){ // 区間和を求める ll sum = (S[N] - S[i + 1]) % mod; // AiAjの計算を行い変数ansに加算し、mod計算を行う ans += sum*A[i]; ans %= mod; } cout << ans << endl; return 0; }
この問題は愚直に2重ループで計算を行っていくとNの制約がのため、
制限時間内に計算を行う事が出来ません。
まずは何か法則性が無いか考えてみましょう。の場合を考えて見ます。
が,,の場合の計算は以下のようにまとめる事が可能です。
※0基算で書いてます。
上記よりに以降の値を足した数を掛け算し、それぞれのでの計算結果を
足し合わせることでも答えが得られそうです。
2重ループで足し算をした後に掛け算を行うと制限時間内に間に合わないので
下記のように累積和をまずは求めます。累積和を求めておけばある区間の和も
で求める事が出来ます。
あとは、に区間和を掛けていきその和を求めていきます。
区間和およびと区間和の積を求める際はmod計算も忘れずに行いましょう。
(オーバーフローの可能性があるため。mod計算は計算途中に行っても計算結果は変わりません。)
最後に計算結果を出力すれば問題を解くことが出来ます。
最後に
うーん今回はもったいなかったですね。ほとんど解けていたようなものだったというのと
割と回答内容に自身があった分、WAが発生した時に余計混乱してしまいました。。。
落ち着いて取り組みましょ!
※累積和の計算段階からmod計算をしていたので、C問題はWAになってしまいました。。。