Submission #373124
Source Code Expand
#include <string>
#include <vector>
#include <algorithm>
#include <numeric>
#include <set>
#include <map>
#include <queue>
#include <iostream>
#include <sstream>
#include <cstdio>
#include <cmath>
#include <ctime>
#include <cstring>
#include <cctype>
#include <cassert>
#include <limits>
#include <functional>
#define rep(i,n) for(int (i)=0;(i)<(int)(n);++(i))
#define rer(i,l,u) for(int (i)=(int)(l);(i)<=(int)(u);++(i))
#define reu(i,l,u) for(int (i)=(int)(l);(i)<(int)(u);++(i))
#if defined(_MSC_VER) || __cplusplus > 199711L
#define aut(r,v) auto r = (v)
#else
#define aut(r,v) __typeof(v) r = (v)
#endif
#define each(it,o) for(aut(it, (o).begin()); it != (o).end(); ++ it)
#define all(o) (o).begin(), (o).end()
#define pb(x) push_back(x)
#define mp(x,y) make_pair((x),(y))
#define mset(m,v) memset(m,v,sizeof(m))
#define INF 0x3f3f3f3f
#define INFL 0x3f3f3f3f3f3f3f3fLL
using namespace std;
typedef vector<int> vi; typedef pair<int,int> pii; typedef vector<pair<int,int> > vpii; typedef long long ll;
template<typename T, typename U> inline void amin(T &x, U y) { if(y < x) x = y; }
template<typename T, typename U> inline void amax(T &x, U y) { if(x < y) x = y; }
typedef int Val;
typedef long long Sum;
struct Node {
int priority;
Node *ch[2];
//ここに欲しい情報(値のsum, 値のmin, etc.)
//splitのためにデフォルトでsizeがある
Val val; int size;
Sum sum;
//情報の初期値を設定する
Node(Val v, int p)
: priority(p)
, val(v), size(1), sum(v) { ch[0] = ch[1] = NULL; }
};
//NULL用に関数を作っておくと便利(Nodeのコンストラクタと同じく初期値に注意)
//addをvalやminiにも足している点に注意。こんなふうにできないと遅延評価はできない
Val val(Node *x) { assert(x); return x->val; }
Sum sum(Node *x) { return !x ? 0 : x->sum; }
int size(Node *x) { return !x ? 0 : x->size; }
Node *update(Node *x) {
//ここで情報の更新を行う
if(!x) return x;
x->size = size(x->ch[0]) + 1 + size(x->ch[1]);
x->sum = sum(x->ch[0]) + x->val + sum(x->ch[1]);
return x;
}
Node *link(Node *x, Node *c, bool b) {
x->ch[b] = c; return update(x);
}
Node *merge(Node *x, Node *y) {
x = update(x); y = update(y);
if(!x || !y) return x ? x : y;
if(x->priority < y->priority) {
return link(x, merge(x->ch[1], y), 1);
}else {
return link(y, merge(x, y->ch[0]), 0);
}
}
//サイズによってsplitする。 ([0,k) , [k,n))
typedef pair<Node*, Node*> NPair;
NPair split(Node *t, int k) {
if(!update(t)) return mp((Node*)NULL, (Node*)NULL);
if(size(t->ch[0]) < k) {
NPair u = split(t->ch[1], k - size(t->ch[0]) - 1);
return mp(link(t, u.first, 1), u.second);
}else {
NPair u = split(t->ch[0], k);
return mp(u.first, link(t, u.second, 0));
}
}
Node *singleton(Val val) { return update(new Node(val, rand())); }
//ソート済みの列に対するlowerbound
int lowerbound(Node *t, Val x) {
if(!update(t)) return 0;
if(x <= val(t)) {
return lowerbound(t->ch[0], x);
}else {
return size(t->ch[0]) + 1 + lowerbound(t->ch[1], x);
}
}
//ソート済みの列に対するinsert
Node *insert(Node *t, Val x) {
int k = lowerbound(t, x);
NPair p = split(t, k);
return merge(p.first, merge(singleton(x), p.second));
}
//ソート済みの列に対するerase
Node *erase(Node *t, Val x) {
int k = lowerbound(t, x);
NPair p = split(t, k);
NPair q = split(p.second, 1);
assert(val(q.first) == x); //存在しない時にどうするかは場合によって書き換えること
delete q.first;
return merge(p.first, q.second);
}
struct DynamicRMQ {
typedef int Val;
int n;
vector<Val> d;
void init(int nmin) {
for(n = 1; n < nmin; n *= 2);
d.assign(n * 2, -INF);
}
void update(int i, Val x) {
d[n+i] = x;
for(int k = (n+i)/2; k > 0; k >>= 1)
d[k] = max(d[k * 2], d[k * 2 + 1]);
}
Val get(int i) const { return d[n+i]; }
//[l, r)
Val query(int l, int r) const {
Val m = -INF;
for(; l && l + (l&-l) <= r; l += l&-l)
m = max(m, d[(n+l) / (l&-l)]);
for(; l < r; r -= r&-r)
m = max(m, d[(n+r) / (r&-r) - 1]);
return m;
}
};
long long solve(ll left, ll right) {
assert(left <= right);
if(0 <= left)
return right;
else if(right <= 0)
return -left;
else
return min(-left, right) + (right - left);
}
int main() {
int N;
scanf("%d", &N);
set<pii> signs;
Node *t = NULL;
const int C = 200001;
vector<set<int> > poses(C);
DynamicRMQ rmqMin, rmqMax;
rmqMin.init(C);
rmqMax.init(C);
rep(i, N) {
int x, a;
scanf("%d%d", &x, &a);
signs.insert(mp(x, a));
poses[a].insert(x);
rmqMin.update(a, -*poses[a].begin());
rmqMax.update(a, *poses[a].rbegin());
t = insert(t, a);
}
int Q;
scanf("%d", &Q);
rep(ii, Q) {
{ int c, y, b;
scanf("%d%d%d", &c, &y, &b);
/*while(1) {
if(signs.empty()||rand()%2==0){
c = 1, y = rand() % 2000 - 1000, b = rand() % 10;
auto it = signs.lower_bound(mp(y,0));
if(it != signs.end() && it->first == y) continue;
}else{
c = 2;
int k = rand() % signs.size();
auto it = signs.begin();
rep(j, k) ++ it;
y = it->first, b = it->second;
}
break;
}*/
if(c == 1) {
signs.insert(mp(y, b));
poses[b].insert(y);
rmqMin.update(b, -*poses[b].begin());
rmqMax.update(b, *poses[b].rbegin());
t = insert(t, b);
}else if(c == 2) {
signs.erase(mp(y, b));
poses[b].erase(y);
rmqMin.update(b, poses[b].empty() ? -INF : -*poses[b].begin());
rmqMax.update(b, poses[b].empty() ? -INF : *poses[b].rbegin());
t = erase(t, b);
}
}
long long ans = INFL;
if((int)signs.size() <= 1) {
puts("0");
continue;
}
int left = signs.begin()->first;
int leftcol = signs.begin()->second;
int right = signs.rbegin()->first;
int rightcol = signs.rbegin()->second;
{ //leftcol,rightcol以外ので塗り替える場合
int num = size(t);
NPair p = split(t, (num-1) / 2);
NPair q = split(p.second, 1);
assert(q.first != 0);
int med = val(q.first);
long long timeSum = 0;
timeSum += (ll)med * size(p.first) - sum(p.first);
timeSum += sum(q.second) - (ll)med * size(q.second);
t = merge(p.first, merge(q.first, q.second));
amin(ans, timeSum + solve(left, right));
}
rep(lr, 2) {
//colで塗り替える場合
int col = lr == 0 ? leftcol : rightcol;
int left2 = min(-rmqMin.query(0, col), -rmqMin.query(col+1, C));
int right2 = max(rmqMax.query(0, col), rmqMax.query(col+1, C));
assert((left2 == INF) == (right2 == -INF));
if(left2 == INF) {
amin(ans, 0);
break;
}
int k = lowerbound(t, col);
NPair p = split(t, k);
long long timeSum = 0;
timeSum += (ll)col * size(p.first) - sum(p.first);
timeSum += sum(p.second) - (ll)col * size(p.second);
t = merge(p.first, p.second);
amin(ans, timeSum + solve(left2, right2));
}
/*ll naiveans = INFL;
each(i, signs) {
int col = i->second;
int left2 = INF, right2 = -INF;
ll x = 0;
each(j, signs) if(j->second != col) {
amin(left2, j->first);
amax(right2, j->first);
x += abs(j->second - col);
}
x += left2 == INF ? 0 : solve(left2, right2);
amin(naiveans, x);
}
if(ans != naiveans)
cerr << ans << " != " << naiveans << endl;*/
printf("%lld\n", ans);
}
return 0;
}
Submission Info
Submission Time |
|
Task |
J - 看板の塗り替え |
User |
anta |
Language |
C++ (GCC 4.9.2) |
Score |
300 |
Code Size |
7521 Byte |
Status |
AC |
Exec Time |
1600 ms |
Memory |
42404 KB |
Compile Error
./Main.cpp: In function ‘int main()’:
./Main.cpp:156:17: warning: ignoring return value of ‘int scanf(const char*, ...)’, declared with attribute warn_unused_result [-Wunused-result]
scanf("%d", &N);
^
./Main.cpp:166:24: warning: ignoring return value of ‘int scanf(const char*, ...)’, declared with attribute warn_unused_result [-Wunused-result]
scanf("%d%d", &x, &a);
^
./Main.cpp:174:17: warning: ignoring return value of ‘int scanf(const char*, ...)’, declared with attribute warn_unused_result [-Wunused-result]
scanf("%d", &Q);
^
./Main.cpp:177:31: warning: ignoring return value of ‘int scanf(const char*, ...)’, declared with attribute warn_unused_result [-Wunused-result]
scanf("%d%d%d", &c, &y, &b);
^
Judge Result
Set Name |
Subtask |
All |
Score / Max Score |
30 / 30 |
270 / 270 |
Status |
|
|
Set Name |
Test Cases |
Subtask |
subtask_00.txt, subtask_01.txt, subtask_02.txt, subtask_03.txt, subtask_04.txt, subtask_05.txt, subtask_06.txt, subtask_07.txt, subtask_08.txt, subtask_09.txt, subtask_10.txt, subtask_11.txt, subtask_12.txt, subtask_13.txt, subtask_14.txt, subtask_15.txt, subtask_16.txt, subtask_17.txt, subtask_18.txt, subtask_19.txt, subtask_20.txt, subtask_21.txt, subtask_22.txt, subtask_23.txt, subtask_24.txt, subtask_25.txt |
All |
scrambled_00.txt, scrambled_01.txt, scrambled_02.txt, scrambled_03.txt, scrambled_04.txt, scrambled_05.txt, scrambled_06.txt, scrambled_07.txt, scrambled_08.txt, scrambled_09.txt, scrambled_10.txt, scrambled_11.txt, scrambled_12.txt, scrambled_13.txt, scrambled_14.txt, scrambled_15.txt, scrambled_16.txt, scrambled_17.txt, scrambled_18.txt, scrambled_19.txt, scrambled_20.txt, scrambled_21.txt, scrambled_22.txt, scrambled_23.txt, scrambled_24.txt, scrambled_25.txt, scrambled_26.txt, subtask_00.txt, subtask_01.txt, subtask_02.txt, subtask_03.txt, subtask_04.txt, subtask_05.txt, subtask_06.txt, subtask_07.txt, subtask_08.txt, subtask_09.txt, subtask_10.txt, subtask_11.txt, subtask_12.txt, subtask_13.txt, subtask_14.txt, subtask_15.txt, subtask_16.txt, subtask_17.txt, subtask_18.txt, subtask_19.txt, subtask_20.txt, subtask_21.txt, subtask_22.txt, subtask_23.txt, subtask_24.txt, subtask_25.txt |
Case Name |
Status |
Exec Time |
Memory |
scrambled_00.txt |
AC |
55 ms |
14244 KB |
scrambled_01.txt |
AC |
1600 ms |
42404 KB |
scrambled_02.txt |
AC |
997 ms |
30756 KB |
scrambled_03.txt |
AC |
704 ms |
28320 KB |
scrambled_04.txt |
AC |
491 ms |
23388 KB |
scrambled_05.txt |
AC |
553 ms |
28580 KB |
scrambled_06.txt |
AC |
1277 ms |
28308 KB |
scrambled_07.txt |
AC |
149 ms |
16156 KB |
scrambled_08.txt |
AC |
1124 ms |
27172 KB |
scrambled_09.txt |
AC |
633 ms |
22040 KB |
scrambled_10.txt |
AC |
237 ms |
20264 KB |
scrambled_11.txt |
AC |
778 ms |
28328 KB |
scrambled_12.txt |
AC |
521 ms |
26664 KB |
scrambled_13.txt |
AC |
208 ms |
17564 KB |
scrambled_14.txt |
AC |
336 ms |
26400 KB |
scrambled_15.txt |
AC |
284 ms |
18428 KB |
scrambled_16.txt |
AC |
1304 ms |
28328 KB |
scrambled_17.txt |
AC |
661 ms |
22572 KB |
scrambled_18.txt |
AC |
289 ms |
18724 KB |
scrambled_19.txt |
AC |
621 ms |
18212 KB |
scrambled_20.txt |
AC |
326 ms |
18080 KB |
scrambled_21.txt |
AC |
1535 ms |
42404 KB |
scrambled_22.txt |
AC |
1345 ms |
28320 KB |
scrambled_23.txt |
AC |
296 ms |
17184 KB |
scrambled_24.txt |
AC |
1057 ms |
25248 KB |
scrambled_25.txt |
AC |
785 ms |
21972 KB |
scrambled_26.txt |
AC |
713 ms |
15908 KB |
subtask_00.txt |
AC |
67 ms |
14756 KB |
subtask_01.txt |
AC |
63 ms |
14752 KB |
subtask_02.txt |
AC |
63 ms |
14496 KB |
subtask_03.txt |
AC |
56 ms |
14372 KB |
subtask_04.txt |
AC |
59 ms |
14496 KB |
subtask_05.txt |
AC |
64 ms |
14488 KB |
subtask_06.txt |
AC |
56 ms |
14376 KB |
subtask_07.txt |
AC |
66 ms |
14508 KB |
subtask_08.txt |
AC |
54 ms |
14244 KB |
subtask_09.txt |
AC |
54 ms |
14308 KB |
subtask_10.txt |
AC |
61 ms |
14496 KB |
subtask_11.txt |
AC |
54 ms |
14244 KB |
subtask_12.txt |
AC |
59 ms |
14504 KB |
subtask_13.txt |
AC |
52 ms |
14364 KB |
subtask_14.txt |
AC |
57 ms |
14240 KB |
subtask_15.txt |
AC |
68 ms |
14496 KB |
subtask_16.txt |
AC |
63 ms |
14488 KB |
subtask_17.txt |
AC |
60 ms |
14364 KB |
subtask_18.txt |
AC |
56 ms |
14236 KB |
subtask_19.txt |
AC |
63 ms |
14492 KB |
subtask_20.txt |
AC |
69 ms |
14752 KB |
subtask_21.txt |
AC |
69 ms |
14500 KB |
subtask_22.txt |
AC |
62 ms |
14372 KB |
subtask_23.txt |
AC |
63 ms |
14364 KB |
subtask_24.txt |
AC |
58 ms |
14372 KB |
subtask_25.txt |
AC |
62 ms |
14372 KB |