結果
問題 | No.121 傾向と対策:門松列(その2) |
ユーザー | uenoku |
提出日時 | 2017-02-21 14:14:16 |
言語 | C++14 (gcc 12.3.0 + boost 1.83.0) |
結果 |
AC
|
実行時間 | 4,436 ms / 5,000 ms |
コード長 | 2,757 bytes |
コンパイル時間 | 1,422 ms |
コンパイル使用メモリ | 116,540 KB |
実行使用メモリ | 128,248 KB |
最終ジャッジ日時 | 2024-06-28 18:44:47 |
合計ジャッジ時間 | 11,829 ms |
ジャッジサーバーID (参考情報) |
judge1 / judge3 |
(要ログイン)
テストケース
テストケース表示入力 | 結果 | 実行時間 実行使用メモリ |
---|---|---|
testcase_00 | AC | 84 ms
8,072 KB |
testcase_01 | AC | 139 ms
10,720 KB |
testcase_02 | AC | 10 ms
5,376 KB |
testcase_03 | AC | 958 ms
82,504 KB |
testcase_04 | AC | 4,436 ms
128,248 KB |
testcase_05 | AC | 899 ms
82,372 KB |
testcase_06 | AC | 841 ms
82,104 KB |
testcase_07 | AC | 987 ms
82,172 KB |
testcase_08 | AC | 998 ms
82,376 KB |
ソースコード
#include "math.h" #include <algorithm> #include <complex> #include <cstdio> #include <iomanip> #include <iostream> #include <map> #include <queue> #include <string> #include <vector> #define ifor(i, a, b) for (int i = (a); i < (b); i++) #define rfor(i, a, b) for (int i = (b)-1; i >= (a); i--) #define rep(i, n) for (int i = 0; i < (n); i++) #define rrep(i, n) for (int i = (n)-1; i >= 0; i--) using namespace std; typedef long double ld; typedef long long int lli; typedef complex<double> P; const double eps = 1e-11; int vex[4] = {1, 0, -1, 0}; int vey[4] = {0, 1, 0, -1}; typedef vector<double> Vec; typedef vector<int> vec; typedef vector<Vec> MAT; typedef vector<vec> mat; lli MOD = 1000000007; template <class T> class bit { public: vector<T> dat; int n; bit(int n) : n(n) { dat.assign(n, 0); } bit(int n, T ini) : n(n) { dat.assign(n, ini); } // sum [0,i) T sum(int i) { int ret = 0; for (--i; i >= 0; i = (i & (i + 1)) - 1) ret += dat[i]; return ret; } // sum [i,j) T sum(int i, int j) { return sum(j) - sum(i); } // add x to i void add(int i, T x) { for (; i < n; i |= i + 1) dat[i] += x; } }; lli n; lli solve(vector<lli> a, lli x) { rep(i, n) { a[i] *= x; } bit<lli> b(n + 20); map<lli, lli> loop; vector<pair<lli, lli>> d; rep(i, n) { d.push_back(make_pair(a[i], i)); loop[a[i]]++; } sort(d.begin(), d.end()); //a_jが中心でa_i,a_jとなるものを考える. lli ans = 0; rep(j, n) { //cout << "LOOP" << j << endl; lli num = d[j].first; //cout << num << endl; vector<lli> ins; rep(l, loop[num]) { lli in = d[j].second; lli left = b.sum(0, in); lli right = b.sum(in, n + 10); ans += left * right; ins.push_back(in); j++; } j--; for (auto k : ins) { b.add(k, 1); } } // ここまででa_i == a_jも含めたものができた. return ans; } int main() { cin >> n; vector<lli> a(n); rep(i, n) cin >> a[i]; //座標圧縮 vector<lli> b(a), left(n, 0), right(n, 0); sort(b.begin(), b.end()); b.erase(unique(b.begin(), b.end()), b.end()); rep(i, n) { a[i] = lower_bound(b.begin(), b.end(), a[i]) - b.begin(); right[a[i]]++; } lli ans = solve(a, 1); ans += solve(a, -1); lli sum = 0; rep(i, n) { } rep(i, n) { sum -= left[a[i]] * right[a[i]]; ans -= sum; left[a[i]]++; right[a[i]]--; sum += left[a[i]] * right[a[i]]; } cout << ans << endl; }