結果
| 問題 |
No.259 セグメントフィッシング+
|
| コンテスト | |
| ユーザー |
vain0
|
| 提出日時 | 2015-08-01 00:22:10 |
| 言語 | C++11(廃止可能性あり) (gcc 13.3.0) |
| 結果 |
WA
|
| 実行時間 | - |
| コード長 | 3,218 bytes |
| コンパイル時間 | 689 ms |
| コンパイル使用メモリ | 78,752 KB |
| 実行使用メモリ | 14,240 KB |
| 最終ジャッジ日時 | 2024-07-18 00:14:46 |
| 合計ジャッジ時間 | 5,541 ms |
|
ジャッジサーバーID (参考情報) |
judge1 / judge3 |
(要ログイン)
| ファイルパターン | 結果 |
|---|---|
| sample | AC * 2 WA * 1 |
| other | AC * 2 WA * 8 TLE * 1 -- * 12 |
ソースコード
#include <string>
#include <vector>
#include <array>
#include <map>
#include <unordered_map>
#include <queue>
#include <algorithm>
#include <iostream>
#include <cstdio>
#include <cstring>
#include <cassert>
using namespace std;
using ull = unsigned long long; using ll = long long;
#define repi(_I, _B, _E) for(int _I = (_B); (_I) < (_E); ++ (_I))
#define rep(_I, _N) for(int _I = 0; (_I) < (_N); ++ (_I))
#define all(_X) begin(_X), end(_X)
//(T, +) semigroup
template<typename T>
struct AddSemigroup
{
static T operate(T const& lhs, T const& rhs) { return lhs + rhs; }
static T unit() { return 0; }
};
template<typename T>
T heightInt(T n)
{
if ( n == 1 ) return 1;
T h = 0;
for ( ; n > static_cast<T>(1 << h); ++h );
return h;
}
template<typename T, typename Semigroup>
class SegTree
{
using uint = unsigned int;
std::vector<T> v_;
uint n_;
uint h_;
public:
void init(int n)
{
n_ = n;
h_ = (heightInt<uint>(n));
assert(n > 1);
v_.resize((1 << h_) * 2 - 1, Semigroup::unit());
}
private:
int nodeIndexFromArrayIndex(int k) const
{
assert(0 <= k && static_cast<uint>(k) < n_);
return ((1 << h_) - 1) + k;
}
public:
T const& at(int k) const { return v_[nodeIndexFromArrayIndex(k)]; }
void update(int k, T const& x)
{
uint i = nodeIndexFromArrayIndex(k);
v_[i] = x;
while ( i != 0 ) {
uint const parent = (i - 1) / 2;
uint const child = parent * 2 + 1;
v_[parent] = Semigroup::operate(v_[child], v_[child + 1]);
i = parent;
}
}
public:
T query(uint begin, uint end)
{
if ( begin >= end ) return Semigroup::unit();
return queryRec(0, 0, 1 << h_, begin, end);
}
private:
T queryRec(uint i, uint nodeBeg, uint nodeEnd, uint queryBeg, uint queryEnd)
{
assert(nodeBeg <= queryBeg && queryBeg < queryEnd && queryEnd <= nodeEnd);
uint const nodeMid = nodeBeg + (nodeEnd - nodeBeg + 1) / 2;
if ( nodeBeg == queryBeg && nodeEnd == queryEnd ) {
return v_[i];
} else if ( queryEnd <= nodeMid ) {
return queryRec(i * 2 + 1, nodeBeg, nodeMid, queryBeg, queryEnd);
} else if ( nodeMid <= queryBeg ) {
return queryRec(i * 2 + 2, nodeMid, nodeEnd, queryBeg, queryEnd);
} else {
assert(queryBeg < nodeMid && nodeMid < queryEnd);
auto const& lhs = queryRec(i * 2 + 1, nodeBeg, nodeMid, queryBeg, nodeMid);
auto const& rhs = queryRec(i * 2 + 2, nodeMid, nodeEnd, nodeMid, queryEnd);
return Semigroup::operate(lhs, rhs);
}
}
};
using ST = SegTree<int, AddSemigroup<int>>;
ST lef, rig;
int i_lef, i_rig;
int t;
int n, q;
int il(int k) { return (k + i_lef) % n; }
int ir(int k) { return (k + i_rig) % n; }
void moveNext()
{
int tmp = lef.at(il(0));
lef.update(il(0), rig.at(ir(n - 1)));
rig.update(ir(n - 1), tmp);
i_lef = (i_lef + 1) % n;
i_rig = (i_rig + n - 1) % n;
++t;
}
int main()
{
cin >> n >> q;
lef.init(n);
rig.init(n);
rep(i, q)
{
int u, y, z;
char c;
cin >> c >> u >> y >> z;
while ( t < u ) {
moveNext();
}
switch ( c ) {
case 'L':
lef.update(il(y), lef.at(il(y)) + z);
break;
case 'R':
rig.update(ir(y), rig.at(ir(y)) + z);
break;
case 'C': {
int s = lef.query(il(y), il(z)) + rig.query(ir(y), ir(z));
cout << s << endl;
break;
}
}
}
return 0;
}
vain0