結果
問題 | No.259 セグメントフィッシング+ |
ユーザー | codershifth |
提出日時 | 2015-12-27 23:43:07 |
言語 | C++11 (gcc 11.4.0) |
結果 |
RE
|
実行時間 | - |
コード長 | 3,294 bytes |
コンパイル時間 | 1,245 ms |
コンパイル使用メモリ | 164,728 KB |
実行使用メモリ | 7,788 KB |
最終ジャッジ日時 | 2024-09-19 07:33:06 |
合計ジャッジ時間 | 6,085 ms |
ジャッジサーバーID (参考情報) |
judge5 / judge4 |
(要ログイン)
テストケース
テストケース表示入力 | 結果 | 実行時間 実行使用メモリ |
---|---|---|
testcase_00 | RE | - |
testcase_01 | RE | - |
testcase_02 | RE | - |
testcase_03 | RE | - |
testcase_04 | RE | - |
testcase_05 | RE | - |
testcase_06 | RE | - |
testcase_07 | RE | - |
testcase_08 | RE | - |
testcase_09 | RE | - |
testcase_10 | RE | - |
testcase_11 | RE | - |
testcase_12 | RE | - |
testcase_13 | RE | - |
testcase_14 | RE | - |
testcase_15 | RE | - |
testcase_16 | RE | - |
testcase_17 | RE | - |
testcase_18 | RE | - |
testcase_19 | RE | - |
testcase_20 | RE | - |
testcase_21 | RE | - |
testcase_22 | RE | - |
testcase_23 | RE | - |
testcase_24 | RE | - |
testcase_25 | RE | - |
ソースコード
#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