結果
問題 | No.151 セグメントフィッシング |
ユーザー | codershifth |
提出日時 | 2015-12-27 23:34:56 |
言語 | C++11 (gcc 11.4.0) |
結果 |
AC
|
実行時間 | 34 ms / 5,000 ms |
コード長 | 3,292 bytes |
コンパイル時間 | 1,346 ms |
コンパイル使用メモリ | 164,232 KB |
実行使用メモリ | 6,944 KB |
最終ジャッジ日時 | 2024-09-19 07:33:00 |
合計ジャッジ時間 | 2,444 ms |
ジャッジサーバーID (参考情報) |
judge1 / judge5 |
(要ログイン)
テストケース
テストケース表示入力 | 結果 | 実行時間 実行使用メモリ |
---|---|---|
testcase_00 | AC | 1 ms
6,812 KB |
testcase_01 | AC | 1 ms
6,944 KB |
testcase_02 | AC | 2 ms
6,944 KB |
testcase_03 | AC | 2 ms
6,940 KB |
testcase_04 | AC | 1 ms
6,944 KB |
testcase_05 | AC | 2 ms
6,944 KB |
testcase_06 | AC | 1 ms
6,940 KB |
testcase_07 | AC | 2 ms
6,944 KB |
testcase_08 | AC | 5 ms
6,940 KB |
testcase_09 | AC | 6 ms
6,940 KB |
testcase_10 | AC | 5 ms
6,940 KB |
testcase_11 | AC | 5 ms
6,944 KB |
testcase_12 | AC | 18 ms
6,940 KB |
testcase_13 | AC | 18 ms
6,940 KB |
testcase_14 | AC | 17 ms
6,940 KB |
testcase_15 | AC | 17 ms
6,940 KB |
testcase_16 | AC | 17 ms
6,940 KB |
testcase_17 | AC | 7 ms
6,944 KB |
testcase_18 | AC | 8 ms
6,944 KB |
testcase_19 | AC | 33 ms
6,940 KB |
testcase_20 | AC | 34 ms
6,944 KB |
testcase_21 | AC | 8 ms
6,940 KB |
testcase_22 | AC | 9 ms
6,940 KB |
testcase_23 | AC | 15 ms
6,944 KB |
ソースコード
#include <bits/stdc++.h> typedef long long ll; typedef unsigned long long ull; #define FOR(i,a,b) for(int (i)=(a);i<(b);i++) #define REP(i,n) FOR(i,0,n) #define RANGE(vec) (vec).begin(),(vec).end() template <typename T> class BIT { public: std::vector<T> data; // [1,n] BIT() {} BIT(int n) { init(n); } void init(int n) { data.resize((1LL<<(int)ceil(log2(n))), 0); } // a[i] += x O(log(n)) void add(int i, int x) { int maxN = data.size()+1; // 2 冪 for (int k = i+1; k <= maxN; k += (k & -k)) data[k-1] += x; } // a[0]+...+a[i] O(log(n)) T sum(int i) { T s = 0; for (int k = i+1; k > 0; k -= (k & -k)) s += data[k-1]; return s; } T operator[](int i) { return sum(i)-sum(i-1); } }; using namespace std; class SegmentFishing { public: void solve(void) { int N,Q; cin>>N>>Q; int t = 0; int B = 2*N; // 配列に含まれる魚を移動するのではなくて,魚の格納インデックスが時間毎に // 変化すると考える。 // 長さ 2*N の配列を考えて N-1 -> N, 2*N -> 0 とリング上につながっていて、 // 0~N-1 が右向き、N~2*n-1 が左向きとみなすことで端の魚の向きの反転を表現できる。 // 区間の総和を計算するには BIT をつかえばよい。 BIT<ll> ring(B); // O(Q*log(N)) while (Q--) { char x; int y,z; cin>>x>>y>>z; switch (x) { case 'R': ring.add((y-t+B)%B, z); break; case 'L': ring.add((B-1-y-t+B)%B, z); break; case 'C': { ll cnt = 0; --z; // [y,z) -> [y,z-1] 閉区間で扱う for (int i = 0; i < 2; ++i) { int l,r; if (i == 0) { l = (y-t+B)%B; r = (z-t+B)%B; } else { r = (B-1-y-t+B)%B; l = (B-1-z-t+B)%B; } ll add = ring.sum(r) - ring.sum(l-1); // 配列の末尾をまたぐケース if (r < l) add += ring.sum(B-1); cnt += add; } cout<<cnt<<endl; } break; default: assert(false); break; } ++t; if (t > B) t-=B; } } }; #if 1 int main(int argc, char *argv[]) { ios::sync_with_stdio(false); auto obj = new SegmentFishing(); obj->solve(); delete obj; return 0; } #endif