結果
| 問題 | No.230 Splarraay スプラレェーイ |
| コンテスト | |
| ユーザー |
btk
|
| 提出日時 | 2015-06-20 03:41:51 |
| 言語 | C++11(廃止可能性あり) (gcc 13.3.0 + boost 1.89.0) |
| 結果 |
AC
|
| 実行時間 | 306 ms / 5,000 ms |
| コード長 | 3,904 bytes |
| 記録 | |
| コンパイル時間 | 571 ms |
| コンパイル使用メモリ | 88,316 KB |
| 実行使用メモリ | 134,600 KB |
| 最終ジャッジ日時 | 2024-07-07 04:37:13 |
| 合計ジャッジ時間 | 4,167 ms |
|
ジャッジサーバーID (参考情報) |
judge3 / judge4 |
(要ログイン)
| ファイルパターン | 結果 |
|---|---|
| sample | AC * 3 |
| other | AC * 17 |
ソースコード
#include<iostream>
#include<fstream>
#include<sstream>
#include<string>
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<ctime>
#include<stack>
#include<queue>
#include<set>
#include<map>
#include<vector>
#include<list>
#include<algorithm>
#include<utility>
#include<complex>
#include<functional>
using namespace std;
#define SZ 1048576
typedef pair<int, int> P;
typedef long long LL;
#define st(x) (x).first
#define ed(x) (x).second
struct seg_Tree{
P interval;//その区間の長さ
LL child;//子供区間の合計値
LL val;//その区間全体に対して更新された値
bool update;//全て同じ値かどうか
int size(){ return(ed(interval) - st(interval) + 1); }
void set(int s, int t){
st(interval) = s, ed(interval) = t;
}
seg_Tree(){
val = child=0;
update = false;
set(1, 0);
}
};
seg_Tree table[SZ*2+1];
seg_Tree used[SZ*2+1];
void make_tree(seg_Tree* tree,int k, int s, int t){
// if(k>SZ*2)printf("%d[%d,%d]\n", k, s, t);
if (s <= t){
tree[k].set(s, t);
if (tree[k].size() > 1){
int l = 2 * k + 1;
int r = l + 1;
make_tree(tree,l, s, (s + t) / 2);
make_tree(tree,r, (s + t) / 2 + 1, t);
}
}
}
LL get(seg_Tree* tree, int k, P len){
int l = 2 * k + 1;//左の子
int r = l + 1;//右の子
if (tree[k].interval == len){
return tree[k].val*tree[k].size()+tree[k].child;
}
//遅延評価
if (tree[k].update){
tree[l].val = tree[k].val; tree[l].child = 0;
tree[r].val = tree[k].val; tree[r].child = 0;
tree[l].update = tree[r].update = true;
}
tree[k].update = false;
tree[k].val = 0;
LL ret;
//真ん中より左側
if (ed(len) <= ed(tree[l].interval)){
ret =get(tree, l, len);
}
//真ん中より右側
else if ((st(len) >= st(tree[r].interval))){
ret = get(tree, r, len);
}
//そうでない
else ret = get(tree, l, make_pair(st(len), ed(tree[l].interval))) + get(tree, r, make_pair(st(tree[r].interval), ed(len)));
tree[k].child = get(tree, l, tree[l].interval) + get(tree, r, tree[r].interval);
return ret;
}
LL add(seg_Tree* tree, int k, P len, LL val){
// printf("[%d,%d][%d,%d](%lld)\n", st(tree[k].interval), ed(tree[k].interval), st(len), ed(len), val);
int l = 2 * k + 1;//左の子
int r = l + 1;//右の子
//区間ぴったし
if (tree[k].interval == len){
tree[k].val = val;
tree[k].child = 0;
tree[k].update = true;
return tree[k].val*tree[k].size();
}
//遅延評価
if (tree[k].update){
tree[l].val =tree[k].val; tree[l].child = 0;
tree[r].val =tree[k].val; tree[r].child = 0;
tree[l].update = tree[r].update = true;
}
tree[k].update = false;
tree[k].val = 0;
//真ん中より左側
if (ed(len) <= ed(tree[l].interval)){
return tree[k].child = add(tree, l, len, val) + get(tree, r, tree[r].interval);
}
//真ん中より右側
if ((st(len) >= st(tree[r].interval)))
return tree[k].child = add(tree, r, len, val) + get(tree, l, tree[l].interval);
//そうでない
return tree[k].child = add(tree, l, make_pair(st(len), ed(tree[l].interval)), val)+add(tree, r, make_pair(st(tree[r].interval), ed(len)), val);
}
int main(void){
int N,Q;
LL A = 0,B = 0;
make_tree(table, 0, 0, SZ);
make_tree(used, 0, 0, SZ);
cin >> N >> Q;
for (int i = 0; i < Q; i++){
int x, l, r;
cin >> x >> l >> r;
switch (x){
case 0:
{
LL dist = get(table, 0, make_pair(l, r));
LL n = get(used, 0, make_pair(l, r));
if (dist>0)A += (n + dist)/2;
else if (dist < 0)B += (n - dist)/2;
}
break;
case 1:
{
add(table, 0, make_pair(l, r), 1);
add(used, 0, make_pair(l, r), 1);
}
break;
case 2:
{
add(table, 0, make_pair(l, r), -1);
add(used, 0, make_pair(l, r), 1);
}
break;
default:
break;
}
// cout << table[0].child << endl;
}
LL dist = get(table, 0, make_pair(0, N-1));
LL n = get(used, 0, make_pair(0, N-1));
A += (n + dist)/2;
B += (n - dist)/2;
cout << A << " " << B << endl;
return(0);
}
btk