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
AC × 26
AC × 53
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