結果
問題 | No.255 Splarrraaay スプラーレェーーイ |
ユーザー | paruki |
提出日時 | 2016-07-29 15:38:10 |
言語 | C++14 (gcc 12.3.0 + boost 1.83.0) |
結果 |
RE
|
実行時間 | - |
コード長 | 5,081 bytes |
コンパイル時間 | 4,524 ms |
コンパイル使用メモリ | 192,048 KB |
実行使用メモリ | 6,816 KB |
最終ジャッジ日時 | 2024-11-06 18:24:07 |
合計ジャッジ時間 | 5,742 ms |
ジャッジサーバーID (参考情報) |
judge4 / judge2 |
(要ログイン)
テストケース
テストケース表示入力 | 結果 | 実行時間 実行使用メモリ |
---|---|---|
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 | - |
ソースコード
#include "bits/stdc++.h" using namespace std; #define FOR(i,j,k) for(int (i)=(j);(i)<(int)(k);++(i)) #define rep(i,j) FOR(i,0,j) #define each(x,y) for(auto &(x):(y)) #define mp make_pair #define all(x) (x).begin(),(x).end() #define debug(x) cout<<#x<<": "<<(x)<<endl #define smax(x,y) (x)=max((x),(y)) #define smin(x,y) (x)=min((x),(y)) #define MEM(x,y) memset((x),(y),sizeof (x)) #define sz(x) (int)(x).size() typedef long long ll; typedef pair<int, int> pii; typedef vector<int> vi; typedef vector<ll> vll; ll N; int Q, M; vll lrVal, X, L, R; const int nTeam = 5; const ll MOD = (ll)1e18 + 9; // 1.5*10^5 * 10^13 = 1.5*10^18 < LLNG_MAX/2 なので // SegTreeの中ではオーバーフローしない。bonusを得た場合だけ加算の時に気をつければ良い。 class SegTreeLazy{ public: int dataSize; vll value, lazyValue; vi lazyClear; SegTreeLazy(int n){ dataSize = 1; while(dataSize < n)dataSize *= 2; int vectorSize = 2 * dataSize - 1; value = lazyValue = vll(vectorSize); lazyClear = vi(vectorSize); } void propagate(int index, int curL, int curR){ if(lazyClear[index])value[index] = 0; // dataSizeは2^k >= M を満たす最小の2^kであるから、 // 2^k > M かもしれない。 // よって、lrValの範囲外参照に注意 value[index] += lazyValue[index] * (lrVal[min(M - 1, curR)] - lrVal[min(M - 1, curL)]); if(curR - curL > 1){ int indexL = index * 2 + 1, indexR = index * 2 + 2; if(lazyClear[index]) lazyValue[indexL] = lazyValue[indexR] = 0; for(int indexC : {indexL, indexR}){ lazyClear[indexC] |= lazyClear[index]; lazyValue[indexC] += lazyValue[index]; } } lazyValue[index] = lazyClear[index] = 0; } // [curL, curR) を評価する void update(int index, int curL, int curR, int givenL, int givenR, int isAdd){ // 評価し終わったら、必ずlazyClear[index]とlazyValue[index]はデフォルト値になっているはず // 範囲外であろうとpropagateは必ず呼ぶ。 propagate(index, curL, curR); // 範囲外 if(curR <= givenL || givenR <= curL)return; if(givenL <= curL && curR <= givenR){ // 直接書き換えないで、lazyClear,lazyValueを更新してからpropagateを呼ぶ if(isAdd){ lazyValue[index]++; } else{ lazyClear[index] = 1; lazyValue[index] = 0; } propagate(index, curL, curR); } else{ int mid = (curL + curR) / 2; update(index * 2 + 1, curL, mid, givenL, givenR, isAdd); update(index * 2 + 2, mid, curR, givenL, givenR, isAdd); value[index] = value[index * 2 + 1] + value[index * 2 + 2]; } } void update(int l, int r, int isAdd){ update(0, 0, dataSize, l, r, isAdd); } ll query(int l, int r){ return query(0, 0, dataSize, l, r); } ll query(int index, int curL, int curR, int givenL, int givenR){ // 範囲外 if(curR <= givenL || givenR <= curL)return 0; propagate(index, curL, curR); if(givenL <= curL && curR <= givenR){ return value[index]; } else{ int mid = (curL + curR) / 2; ll resL = query(index * 2 + 1, curL, mid, givenL, givenR); ll resR = query(index * 2 + 2, mid, curR, givenL, givenR); return resL + resR; } } }; int main(){ cin >> N >> Q; X = L = R = vll(N); // 区間の座標圧縮 rep(i, Q){ scanf("%lld%lld%lld", &X[i], &L[i], &R[i]); for(ll val : {L[i], L[i] + 1, R[i], R[i] + 1}) lrVal.push_back(val); } sort(all(lrVal)); lrVal.erase(unique(all(lrVal)), lrVal.end()); M = sz(lrVal); vector<SegTreeLazy> segTree(nTeam, SegTreeLazy(M)); vll ans(nTeam); rep(q, Q){ int x = (int)X[q], l = (int)L[q], r = (int)R[q]; // チームのインデックスを0-Originにしておく --x; // [l,r] => [l, r) r++; if(x == -1){ vector<pair<ll, int>> bonusAndTeam(nTeam); rep(i, nTeam){ bonusAndTeam[i] = mp(segTree[i].query(l, r), i); } sort(bonusAndTeam.rbegin(), bonusAndTeam.rend()); ll bonus = bonusAndTeam[0].first; // トップタイがいたら、ボーナス無し if(bonus != bonusAndTeam[1].first){ (ans[bonusAndTeam[0].second] += bonus) %= MOD; } } else{ rep(i, nTeam){ if(i == x)segTree[i].update(l, r, 1); else segTree[i].update(l, r, 0); } } } rep(i, nTeam){ (ans[i] += segTree[i].query(0, M)) %= MOD; printf("%lld%c", ans[i], i != nTeam - 1 ? ' ' : '\n'); } }