Submission #61028

#TimeUsernameProblemLanguageResultExecution timeMemory
61028zetapiJousting tournament (IOI12_tournament)C++14
100 / 100
298 ms33880 KiB
#include <bits/stdc++.h> using namespace std; #define pb push_back #define mp make_pair //#define int long long #define itr ::iterator typedef pair<int,int> pii; const int MAX=5e5; set<int> st; set<int> itr it; vector<pii> query; vector<int> vec[MAX]; pii dp[MAX]; int N,R,res,lol,rep[MAX],arr[MAX],deg[MAX],start[MAX],finish[MAX]; struct SegTree { vector<pii> seg; SegTree() { } void init(int N) { seg.resize(4*N); return ; } void build(int low,int high,int node) { if(low==high) { seg[node]=mp(arr[low],1); return ; } int mid=(low+high)/2; build(low,mid,2*node); build(mid+1,high,2*node+1); seg[node].first=max(seg[2*node].first,seg[2*node+1].first); seg[node].second=seg[2*node].second+seg[2*node+1].second; return ; } void update(int low,int high,int node,int idx) { if(low==high) { seg[node].second=0; return ; } int mid=(low+high)/2; if(idx>=low and idx<=mid) update(low,mid,2*node,idx); else update(mid+1,high,2*node+1,idx); seg[node].second=seg[2*node].second+seg[2*node+1].second; return ; } int get(int low,int high,int node,int idx) { if(low==high) return low; int mid=(low+high)/2; if(seg[2*node].second>=idx) return get(low,mid,2*node,idx); else return get(mid+1,high,2*node+1,idx-seg[2*node].second); } int query(int low,int high,int node,int qlow,int qhigh) { if(low>high or qlow>qhigh or qhigh<low or qlow>high) return 0; if(low>=qlow and high<=qhigh) return seg[node].first; int mid=(low+high)/2; return max(query(low,mid,2*node,qlow,qhigh),query(mid+1,high,2*node+1,qlow,qhigh)); } } S; void ConstructTree() { st.clear(); int l,r,cur=N+1; for(int A=1;A<=N;A++) { rep[A]=A; st.insert(A); } for(auto A:query) { l=S.get(1,N,1,A.first); r=S.get(1,N,1,A.second); //cout<<l<<" "<<r<<"\n"; for(it=st.lower_bound(l);it!=st.end();it++) { if(*it>r) break; vec[cur].pb(rep[*it]); deg[rep[*it]]++; if(*it!=l) S.update(1,N,1,*it); } rep[l]=cur++; //cout<<*st.lower_bound(l)<<" "<<*st.lower_bound(r)<<"ha ha \n"; st.erase(st.upper_bound(l),st.upper_bound(r)); } return ; } void dfs(int node,int hei) { dp[node]=mp(0,node); start[node]=node<=N?node:4*N; finish[node]=node<=N?node:0; for(auto A:vec[node]) { dfs(A,hei+1); start[node]=min(start[node],start[A]); finish[node]=max(finish[node],finish[A]); if(dp[A].first+1>dp[node].first) { dp[node]=dp[A]; dp[node].first++; } else if(dp[A].first+1==dp[node].first) dp[node].second=min(dp[node].second,dp[A].second); } //cout<<node<<" start "<<start[node]<<" finish "<<finish[node]<<" "<<dp[node].first<<" "<<dp[node].second<<"\n"; if(S.query(1,N,1,start[node],finish[node]-1)<R) { if(dp[node].first>res) lol=dp[node].second; else if(dp[node].first==res) lol=min(lol,dp[node].second); res=max(res,dp[node].first); } return ; } int GetBestPosition(int n, int C, int r, int *K, int *S_, int *E_) { res=0; lol=1; N=n,R=r; for(int A=0;A<N;A++) arr[A+1]=K[A]; S.init(N); S.build(1,N,1); for(int A=0;A<C;A++) query.pb(mp(S_[A]+1,E_[A]+1)); ConstructTree(); for(int A=1;A<=N+C;A++) if(!deg[A]) dfs(A,0); return lol-1; } /*signed main() { ios_base::sync_with_stdio(false); int K[]={1,0,2,4},seg[]={1,0,0},E[]={3,1,1}; cout<<GetBestPosition(5,3,3,K,seg,E); return 0; }*/
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...