제출 #542233

#제출 시각아이디문제언어결과실행 시간메모리
542233wildturtle팀들 (IOI15_teams)C++17
100 / 100
3693 ms166532 KiB
#include "teams.h"
#include<bits/stdc++.h>
#define ll long long
#define f first
#define sc second
#define pb push_back
using namespace std;
int a[500005],b[500005],n,m;
int tree[40*500005],lef[40*500005],righ[40*500005];
int root[500005],k[500005],dp[500005];
int snode,prevroot;
set <int> st1;
set < pair <int,int> > st;
vector <int> v[500005];
inline void build(int node,int le,int ri) {
    if(le==ri) {
        tree[node]=0;
        return;
    }
    snode++;
    lef[node]=snode;
    build(snode,le,(le+ri)/2);
    snode++;
    righ[node]=snode;
    build(snode,(le+ri)/2+1,ri);
    tree[node]=tree[lef[node]]+tree[righ[node]];
}
inline void update(int node,int prevnode,int le,int ri,int idx) {
    if(ri<idx || le>idx) return;
    if(le==ri) {
        tree[node]=tree[prevnode]+1;
        return;
    }
    if(idx<=(le+ri)/2) { 
        snode++; lef[node]=snode; righ[node]=righ[prevnode];
        update(snode,lef[prevnode],le,(le+ri)/2,idx); 
    } else {
        snode++; righ[node]=snode; lef[node]=lef[prevnode];
        update(snode,righ[prevnode],(le+ri)/2+1,ri,idx);
    }
    tree[node]=tree[lef[node]]+tree[righ[node]];
    
}
inline int getans(int node,int start,int end,int le,int ri) {
    if(ri<start || le>end) return 0;
    if(start<=le && ri<=end) return tree[node];
return getans(lef[node],start,end,le,(le+ri)/2)+getans(righ[node],start,end,(le+ri)/2+1,ri);
}
inline int Z(int x,int y) {
    return getans(root[y],y,n,1,n)-getans(root[x],y,n,1,n);
}
inline int go(int x,int y) {
    int le=k[y]+1; 
    int ri=n;
    int ans=0;
    while(le<=ri) {
        int mid=(le+ri)/2;
        if(dp[x]-dp[y]< -(getans(root[k[y]],mid,n,1,n)-getans(root[k[x]],mid,n,1,n))) {
            ans=mid; ri=mid-1;
        } else le=mid+1;
    }
    return ans;
}
inline void add(int x) {
    st1.insert(x);
    if (!st1.size()) return;
    int pat = -1, did = -1;
    int tim;
    if (*st1.begin() < x) pat = *(--st1.lower_bound(x));
    if (st1.upper_bound(x) != st1.end()) did = *st1.upper_bound(x);
    if (pat != -1 && did != -1) {
        tim = go(pat, did);
        if (tim) st.erase({tim,did});
    }
    if (pat != -1) {
        tim = go(pat,x);
        if (tim) st.insert({tim,x});
    }
    if (did != -1) {
        tim = go(x, did);
        if (tim) st.insert({tim,did});
    }
}
inline void del(int x) {
    if(!st1.count(x)) return;
    st1.erase(x);
    if(!st1.size()) return;
    int pat=-1;
    int did=-1;
    if(*st1.begin()<x) pat=*(--st1.upper_bound(x));
    if(st1.upper_bound(x)!=st1.end()) did=*st1.upper_bound(x);
    int tim;
    if(did!=-1) {
        tim=go(x,did);
        if(tim) st.erase({tim,did});
    }
    if(pat!=-1) {
        tim=go(pat,x);
        if(tim) st.erase({tim,x});
    }
    if(did!=-1 && pat!=-1) {
        tim=go(pat,did);
        if(tim) st.insert({tim,did});
    }
}
int can(int M, int K[]) {
    st.clear();
    st1.clear();
    m=M;
    for(int i=1;i<=m;i++) {
        k[i]=K[i-1];
        dp[i]=0;
    }
    int sum=0;
	for(int i=1;i<=m;i++) {
	    sum+=k[i];
	}
	if(sum>n) return 0;
	sort(k+1,k+1+m);
	dp[0]=0;
	add(0);
	for(int i=1;i<=m;i++) dp[i]=1e9;
	for(int i=1;i<=m;i++) {
	    while(st.size()) {
	    	multiset < pair <int,int> > :: iterator it = st.begin();
	        if((*it).f<=k[i]) del((*it).sc);
	        else break;
	    }
	    int idx=*(--st1.end());
	    dp[i]=dp[idx]+Z(k[idx],k[i])-k[i];
	    if(dp[i]<0) return 0;
	    add(i);
	}
	return 1;
}
void init(int N, int A[], int B[]) {
    n=N;
    for(int i=1;i<=n;i++) {
        a[i]=A[i-1]; b[i]=B[i-1];
	    v[a[i]].pb(b[i]);
	}
	snode=1;
	root[0]=snode;
	build(1,1,n);
	for(int i=1;i<=n;i++) {
        prevroot=root[i-1];
        root[i]=root[i-1];
        for(int j=0;j<v[i].size();j++) {
            snode++;
            root[i]=snode;
            update(root[i],prevroot,1,n,v[i][j]);
            prevroot=root[i];
        }
	}
}

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

teams.cpp: In function 'void init(int, int*, int*)':
teams.cpp:148:22: warning: comparison of integer expressions of different signedness: 'int' and 'std::vector<int>::size_type' {aka 'long unsigned int'} [-Wsign-compare]
  148 |         for(int j=0;j<v[i].size();j++) {
      |                     ~^~~~~~~~~~~~
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...