제출 #604503

#제출 시각아이디문제언어결과실행 시간메모리
604503balbit팀들 (IOI15_teams)C++14
0 / 100
4057 ms286196 KiB
#include "teams.h"
#include <bits/stdc++.h>
#pragma GCC optimize("O3")
using namespace std;

// #undef BALBIT
// #define int ll

#define ll long long
#define pii pair<int, int>
#define f first
#define s second

#define FOR(i,a,b) for (int i = a; i<b; ++i) 
#define REP(i,n) FOR(i,0,n)
#define REP1(i,n) FOR(i,1,n+1)

#define MX(a,b) a = max(a,b)
#define MN(a,b) a = min(a,b)
#define SZ(x) (int)((x).size())
#define ALL(x) (x).begin(), (x).end()
#define pb push_back

#ifdef BALBIT
#define bug(...) cerr<<"#"<<__LINE__<<":"<<#__VA_ARGS__<<"- ", _do(__VA_ARGS__)
template<typename T> void _do(T && x) {cerr<<x<<endl;}
template<typename T, typename ...S> void _do(T && x, S && ...y) {cerr<<x<<", "; _do(y...);}
#else
#define bug(...)
#define endl '\n'
#endif

namespace {
	const int maxn = 5e5+10;
	const ll inf = 0x3f3f3f3f3f3f3f3f;
	const int BA= 70;
}
int N;
vector<pii> seg;

namespace MAO{
	
	int lc[maxn*BA/2], rc[maxn*BA/2], val[maxn*BA];
	int history[maxn];
	int IT = 1;
	int MO(int p, int o, int l, int r) {
		if (l > p || r < p) return o;
		int NO = ++IT;
		val[NO] = val[o] + 1;
		if (l == r) {
			return NO;
		}
		int mid = (l+r)/2;
		lc[NO] = MO(p,lc[o],l,mid);
		rc[NO] = MO(p,rc[o],mid+1,r);
		return NO;
	}
	int build(int l, int r) {
		int NO = ++IT;
		if (l == r) {
			return NO;
		}
		int mid = (l+r)/2;
		lc[NO] = build(l,mid); rc[NO] = build(mid+1,r);
		return NO;
	}
	int QU(int L, int R, int o, int l, int r) {
		// bug(p,l,r,o,val[o]);
		if (L > R) return 0;
		if (l >= L && r <= R) {
			return val[o];
		}
		if (l > R || r < L) return 0;
		int mid = (l+r)/2;
		return QU(L,R,lc[o],l,mid) +QU(L,R,rc[o],mid+1,r);
	}
}



int get(int L, int Ra, int Rb) {
	// temporary function
	// returns the number of segments with index >= L && right value >= R
	// to be replaced by segtree later
	// int re = 0;
	// for(int i = L; i<N; ++i) {
	// 	if(seg[i].s >= R) re++;
	// }
	// return re;
	if (L >= N || Ra > N || max(0,Ra-1) > Rb) return 0;
	// bug(L,R);
	MX(L, 0);
	int ret = MAO::QU(max(0,Ra-1), Rb-1,MAO::history[L],0,N-1);
	return ret;
}

void init(signed NN, signed A[], signed B[]) {
	memset(MAO::lc, -1, sizeof MAO::lc);
	memset(MAO::rc, -1, sizeof MAO::rc);
	memset(MAO::val, 0, sizeof MAO::val);
	N = NN;
	seg.clear();
	REP(i,N) {
		seg.pb({A[i], B[i]});
	}
	sort(ALL(seg));
	REP(i, N)bug(i,seg[i].f,seg[i].s);
	MAO::history[N] = MAO::build(0, N-1);
	bug(MAO::history[N]);
	for(int i = N-1; i>=0; --i) {
		MAO::history[i] = MAO::MO(seg[i].s-1,MAO::history[i+1],0,N-1);
	}
	// bug(MAO::QU(0,MAO::history[0],0,N-1));
	// bug(MAO::QU(1,MAO::history[0],0,N-1));
	// bug(MAO::QU(2,MAO::history[0],0,N-1));
	// bug(MAO::QU(3,MAO::history[0],0,N-1));
}

struct item{
	int L, R;
};

signed can(signed M, signed K[]) {
	bug(M);
	map<int, int> take;
	REP(i,M) {
		take[K[i]]+=K[i];
		if (take[K[i]] > N) return 0;
	}
	vector<pii> tmp;
	for(pii p :take) {
		tmp.pb(p);
	}
	sort(ALL(tmp), greater<pii>());

	vector<item > stk; // {L, R}
	stk.pb({-1, N+1});
	int goback = N;
	for (auto PPP :tmp) {
		int R = PPP.f;
		int need = PPP.s;
		while(goback-1 >= 0 && seg[goback-1].f > R) --goback;
		int lastl = goback;
		while (!stk.empty()) {
			int sL = stk.back().L, sR = stk.back().R; 
			if (sL >= lastl) {
				stk.pop_back(); continue;
			}
			// indicates that, of all segments of index in [sL, lastl), 
			// anything with right value >= sR was taken
			int prv = lastl; lastl = sL;
			int haverem = -get(sL, R, sR-1) 
						 +get(prv, R, sR-1);

			// (get(sL,R) - get(prv,R)) - (get(sL,sR) - get(prv, sR));

			bug(haverem);
			if (haverem < need) {
				need -= haverem;
				stk.pop_back();
				continue;
			}else if (haverem == need) {
				bug(haverem, need);
				need -= haverem;
				stk.back().R = R; 
				break;
			}else{
				bug(need);
				int bl = sL + 1, br = prv - 1;
				ll fix = get(prv, R,sR-1);
				while (bl != br) {
					int mid = (bl +br) / 2;
					int yum = fix - get(mid, R, sR-1) ;
					bug(bl, br, mid, yum);
					bug(prv, sR, R);
					// if (yum == need){
					// 	bl = br = mid; break;
					// }
					if(yum > need) {
						bl = mid+1;
					}else{
						br = mid;
					}
				}
				bug("add", bl, R);
				stk.push_back({bl, R});
				break;
			}
		}
		if(stk.empty()) return 0;
	}
	bug("yay");
	
	return 1;
}
/*
8
1 4
2 3
2 3
2 3
2 3
2 4
2 4
2 4
1
3 2 3 4

*/

컴파일 시 표준 에러 (stderr) 메시지

teams.cpp: In function 'int can(int, int*)':
teams.cpp:173:20: warning: conversion from 'long long int' to 'int' may change value [-Wconversion]
  173 |      int yum = fix - get(mid, R, sR-1) ;
      |                ~~~~^~~~~~~~~~~~~~~~~~~
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...