제출 #606797

#제출 시각아이디문제언어결과실행 시간메모리
6067978e7팀들 (IOI15_teams)C++17
100 / 100
613 ms203992 KiB
//Challenge: Accepted
#include <bits/stdc++.h>
#pragma GCC optimize("Ofast")
using namespace std;
#ifdef zisk
void debug(){cout << endl;}
template<class T, class ... U> void debug(T a, U ... b){cout << a << " ", debug(b...);}
template<class T> void pary(T l, T r){
	while (l != r) cout << *l << " ", l++;
	cout << endl;
}
#else
#define debug(...) 0
#define pary(...) 0
#endif
#define ll long long
#define maxn 500005
#define pii pair<int, int>
#define ff first
#define ss second
#include "teams.h"
struct segtree{
	vector<int> seg[4*maxn];
	void build(int cur, int l, int r, vector<pii> a) {
		if (r <= l || a.size() == 0) return;
		if (r - l == 1) {
			for (auto p:a) seg[cur].push_back(p.ss);
			sort(seg[cur].begin(), seg[cur].end());
			return;
		}
		int m = (l + r) / 2;
		vector<pii> lef, rig;	
		for (auto p:a) {
			if (p.ff < m)lef.push_back(p);
			else rig.push_back(p);
		}
		build(cur*2, l, m, lef), build(cur*2+1, m, r, rig);
		int ls = seg[cur*2].size(), rs = seg[cur*2+1].size();
		vector<int> &le = seg[cur*2], &ri = seg[cur*2+1];
		int ind = 0;
		for (int i = 0;i < ls;i++) {
			while (ind < rs && ri[ind] < le[i]) seg[cur].push_back(ri[ind++]);
			seg[cur].push_back(le[i]);
		}
		while (ind < rs) seg[cur].push_back(ri[ind++]);
	}
	int query(int cur, int l, int r, int ql, int qr) {
		//number of segments covering [ql, qr]
		if (r <= l || l > ql) return 0;
		if (r-1 <= ql) {
			int ind = lower_bound(seg[cur].begin(), seg[cur].end(), qr) - seg[cur].begin();
			return (int)seg[cur].size() - ind;
		}
		int m = (l + r) / 2;
		return query(cur*2, l, m, ql, qr) + query(cur*2+1, m, r, ql, qr);
	}
} tr;

int v[maxn];
int n;
void init(signed N, signed A[], signed B[]) {
	n = N;
	vector<pii> a(n);
	for (int i = 0;i < n;i++) {
		a[i] = {A[i], B[i]};
		v[A[i]]++;
		v[B[i] + 1]--;
	}
	tr.build(1, 1, N+1, a);
	for (int i = 1;i <= n;i++) v[i] += v[i-1]; //number of segments covering i
}


signed can(signed m, signed num[]) {
	sort(num, num + m);
	vector<int> c(m, 0), dp(m, 0);
	int tot = 0;
	for (int i = 0;i < m;i++) {
		tot += num[i];
		c[i] = v[num[i]] - num[i];
		dp[i] = c[i];
		if (c[i] < 0 || tot > n) return 0;
	}
	vector<int> stk, pnt;
	auto f = [&] (int l, int r){
		return c[r] + dp[l] - tr.query(1, 1, n+1, num[l], num[r]);
	};
	
	for (int i = 0;i < m;i++) {
		while (stk.size() > 1 && pnt.back() < i) {
			stk.pop_back();
			pnt.pop_back();
		}
		if (stk.size()) {
			dp[i] = min(dp[i], f(stk.back(), i));
			if (dp[i] < 0) return 0;
		}
		if (i < m - 1) {
			bool done = 0;
			while (stk.size()) {
				if (f(stk.back(), pnt.back()) >= f(i, pnt.back())) {
					stk.pop_back();
					pnt.pop_back();
					continue;
				}
				if (f(stk.back(), i+1) <= f(i, i+1)) {
					done = 1;
					break;
				}
				int low = i+1, up = pnt.back();
				while (low < up - 1) {
					int mid = (low + up) / 2;
					if (f(stk.back(), mid) > f(i, mid)) low = mid;	
					else up = mid;
				}
				stk.push_back(i);
				pnt.push_back(low);
				done = 1;
				break;
			}
			if (!done && stk.size() == 0) {
				stk.push_back(i);
				pnt.push_back(m-1);	
			}
		}
	}
	return 1;
}
/*
   4 
   2 3 1 1 
   3 4 4 4 
   1 
   4
 */

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

teams.cpp: In member function 'void segtree::build(int, int, int, std::vector<std::pair<int, int> >)':
teams.cpp:38:27: warning: conversion from 'std::vector<int>::size_type' {aka 'long unsigned int'} to 'int' may change value [-Wconversion]
   38 |   int ls = seg[cur*2].size(), rs = seg[cur*2+1].size();
      |            ~~~~~~~~~~~~~~~^~
teams.cpp:38:53: warning: conversion from 'std::vector<int>::size_type' {aka 'long unsigned int'} to 'int' may change value [-Wconversion]
   38 |   int ls = seg[cur*2].size(), rs = seg[cur*2+1].size();
      |                                    ~~~~~~~~~~~~~~~~~^~
teams.cpp: In member function 'int segtree::query(int, int, int, int, int)':
teams.cpp:51:64: warning: conversion from '__gnu_cxx::__normal_iterator<int*, std::vector<int> >::difference_type' {aka 'long int'} to 'int' may change value [-Wconversion]
   51 |    int ind = lower_bound(seg[cur].begin(), seg[cur].end(), qr) - seg[cur].begin();
      |              ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~^~~~~~~~~~~~~~~~~~
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...