제출 #402333

#제출 시각아이디문제언어결과실행 시간메모리
402333oolimry팀들 (IOI15_teams)C++17
100 / 100
1683 ms101076 KiB
#include "teams.h"
#include <bits/stdc++.h>
using namespace std;
#define all(x) (x).begin(), (x).end()
#define sz(x) ((int) x.size())
#define show(x) cerr << #x << " is " << x << endl;
#define show2(x, y) cerr << #x << " is " << x << ", " << #y << " is " << y << endl;
#define show3(x, y, z) cerr << #x << " is " << x << ", " << #y << " is " << y << ", " << #z << " is " << z << endl;
typedef long long lint;
typedef pair<int, int> ii;

///segment tree begin
const int N = 1 << 19;
vector<int> tree[2*N];
inline void update(int a, int b){
	for(b += N;b > 0;b >>= 1) tree[b].push_back(a);
}
inline void getready(){
	for(int i = 0;i < 2*N;i++) sort(all(tree[i]));
}
inline int get(int u, int a, int A){
	return upper_bound(all(tree[u]), A) - lower_bound(all(tree[u]), a);
}
inline int querypos(int a, int A, int need){
	int u = 1;
	for(int i = 1;i <= 19;i++){
		int lc = u<<1; int rc = lc+1;
		int G = get(rc,a,A);
		if(need > G){
			need -= G;
			u = lc;
		}
		else u = rc;
	}
	return u-N;
}
inline int query(int a, int A, int l, int r){
	int res = 0;
	for(l += N, r += N+1;l < r;l >>= 1, r >>= 1){
		if(l&1) res += get(l++,a,A);
		if(r&1) res += get(--r,a,A);
	}
	return res;
}
///segment tree end

int cross[500005];
void init(int n, int A[], int B[]) {
	for(int i = 0;i < n;i++) update(A[i], B[i]);
	getready();
	for(int i = 0;i < n;i++) cross[A[i]]++, cross[B[i]+1]--;
	for(int i = 1;i <= 500000;i++) cross[i] += cross[i-1];
}

map<int,int> best;
priority_queue<ii, vector<ii>, greater<ii> > pq;

void create(int i){
	auto b = best.find(i);
	assert(b != best.begin() and b != best.end());
	auto a = prev(b);
	int diff = b->second - a->second;
	
	
	int C = querypos(a->first+1, b->first, diff) + 1;
	pq.push(ii(C,b->first));
}

void insert(int i, int dp){
	if(best.empty()){
		best[i] = dp;
		return;
	}
	best[i] = dp;
	create(i);
}

void process(int limit){
	while(!pq.empty()){
		ii T = pq.top(); 
		if(T.first > limit) break;
		pq.pop();
		
		int i = T.second;
		auto it = best.find(i);
		if(it == best.end()) continue;
		
		auto nxtit = next(it);
		int nxt = -1;
		if(nxtit != best.end()) nxt = nxtit->first;
		
		best.erase(it);
		if(nxt != -1) create(nxt);
	}
}

int can(int M, int K[]) {
	best.clear(); while(!pq.empty()) pq.pop();
	sort(K,K+M);
	
	long long total = 0;
	for(int i = 0;i < M;i++) total += K[i];
	if(total > 500000) return 0; ///idk why preemptive pruning
	
	int acc = 0;
	for(int i = 0;i < M;i++){
		acc += K[i];
		if(i != M-1 and K[i] == K[i+1]) continue; ///accumulate the queries
		
		process(K[i]);
				
		int dp = cross[K[i]]; ///dp = children - projects, if dp goes negative then return 0
		if(not best.empty()){
			auto it = best.end(); it--;
			dp = min(dp, it->second + query(it->first+1, K[i], K[i], N-1));
		}


		dp -= acc;
		if(dp < 0) return 0;
		
		insert(K[i], dp);		
		
		acc = 0;
	}
	return 1;
}

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

teams.cpp: In function 'int get(int, int, int)':
teams.cpp:22:38: warning: conversion from '__gnu_cxx::__normal_iterator<int*, std::vector<int> >::difference_type' {aka 'long int'} to 'int' may change value [-Wconversion]
   22 |  return upper_bound(all(tree[u]), A) - lower_bound(all(tree[u]), a);
      |         ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...