Submission #168665

#TimeUsernameProblemLanguageResultExecution timeMemory
168665CaroLindaTeams (IOI15_teams)C++14
100 / 100
1889 ms163904 KiB
#include <bits/stdc++.h> #include "teams.h" #define debug #define lp(i,a,b) for(int i = a ; i < b ; i++ ) #define ff first #define ss second #define pb push_back #define mk make_pair #define ll long long #define sz size() #define pii pair<int,int> #define all(x) x.begin(),x.end() #define tiii tuple<int,int,int, int> #define mkt make_tuple const int MAXN = 5e5+10 , MAX = 1e6+10 ; using namespace std ; struct Seg { vector<int> e , d , soma ; int m(int l, int r) { return (l+r)>>1 ; } int create() { e.pb( 0 ) ; d.pb( 0 ) ; soma.pb( 0 ) ; return (int)(e.sz) - 1 ; } int create_and_copy(int pos) { e.pb( e[pos] ) ; d.pb( d[pos] ) ; soma.pb( soma[pos] ) ; return (int)(e.sz) - 1 ; } int upd(int pos, int l, int r, int idx ) { int novo = create_and_copy(pos) ; if( l == r ) { soma[novo] ++ ; return novo ; } int aux ; if( idx <= m(l,r) ) { aux = upd(e[novo] , l, m(l,r) , idx ) ; e[novo] = aux ; } else { aux = upd(d[novo] ,m(l,r)+1, r , idx ) ; d[novo] = aux ; } soma[novo] = soma[ e[novo] ] + soma[ d[novo] ] ; return novo ; } int bbp(int v1, int v2, int l, int r, int& val ) { if( l == r ) { val -= soma[v2] - soma[v1] ; return l ; } int aux = soma[ e[v2] ] - soma[ e[v1] ] ; if( aux >= val ) return bbp( e[v1] , e[v2] , l , m(l,r) , val ) ; val -= aux ; return bbp( d[v1] , d[v2] , m(l,r)+1, r, val ) ; } int qry(int pos, int l, int r, int beg, int en) { if( l > en || r < beg ) return 0 ; if( l >= beg && r <= en ) return soma[pos] ; int al = qry(e[pos] , l , m(l,r) , beg, en) ; int ar = qry(d[pos] , m(l,r)+1, r, beg, en ) ; return al + ar ; } void print(int pos, int l, int r) { if( l == r ) return (void)( printf("%d ", soma[pos]) ) ; print(e[pos] , l, m(l,r)) ; print(d[pos],m(l,r)+1, r) ; } } ; //Declarations int n , q , m , cnt = 1 ; int A[MAXN] , B[MAXN] , version[MAX] , isThere[MAX+5] ; vector< tuple<int,int,int> > littleCompr , untitled ; Seg seg ; int find(int val, int t) { //T == 0 -> procura o menor de todos cuja compressao eh maior ou igual a val //T == 1 -> procura o maior de todos cuja compressao eh menor ou igual a val int l = 0 , r = (int)( littleCompr.sz ) - 1 , mid , best=0; if( t == 0 && get<0>(littleCompr[r]) < val ) return -1 ; while( l <= r ) { mid = (l+r)>>1 ; if( t == 0 ) { if( get<0>(littleCompr[mid]) >= val ) { best = mid ; r = mid - 1 ; } else l = mid + 1 ; } else { if( get<0>(littleCompr[mid]) <= val ) { best = mid ; l = mid+1 ; } else r = mid -1 ; } } return best + 1 ; } bool processQuery() { stack< tuple<int,int,int> > pilha ; sort( all(untitled) ) ; // begL , enL , limR pilha.push( mkt( 0 , 0 , MAX ) ) ; bool isPossible = true ; for(auto p : untitled ) { int x = get<0>(p) , y = get<1>(p) , val = get<2>(p) ; int fineLine = y ; while( val ) { //printPile() ; if( pilha.sz == 0 ) { isPossible = false ; break ; } tuple<int,int,int> cur = pilha.top() ; int enL = get<1>(cur) , limR = get<2>(cur) ; if( limR < fineLine ) { pilha.pop() ; continue ; } val += seg.qry( version[x] , 0 , MAX , 0,fineLine-1 ) - seg.qry(version[enL] , 0 , MAX ,0, fineLine-1 ) ; int couldBe = seg.qry( version[x] , 0 , MAX , 0,limR ) - seg.qry( version[enL] , 0 ,MAX , 0,limR ) ; if( val > couldBe ) { pilha.pop() ; fineLine = limR+1 ; val -= couldBe ; continue ; } fineLine = seg.bbp( version[ enL ] , version[ x ] , 0 , MAX , val ) ; pilha.push( mkt( enL , x , fineLine ) ) ; } if( !isPossible ) break ; } return isPossible ; } void init(int N, int a[], int b[]) { seg.create() ; n = N ; lp(i,1,n+1) A[i] = a[i-1] , B[i] = b[i-1] ; //Little compression //This way, nobody will have the same R //Makes life easier lp(i,1,n+1) { littleCompr.pb( mkt( A[i] , 0 , i ) ) ; littleCompr.pb( mkt( B[i] , 1 , i ) ) ; } sort( littleCompr.begin() , littleCompr.end() ) ; for(auto p : littleCompr ) { int type = get<1>(p) , id = get<2>(p) ; int& ref = ( type == 0 ? A[id] : B[id] ) ; ref = cnt ++ ; if( type == 0 ) isThere[ref] = id ; } //Updating the segment tree for(int i = 1 ; i <= MAX ; i++ ) { if( isThere[i] == 0 ) { version[i] = version[i-1] ; continue ; } version[i] = seg.upd( version[i-1] , 0 , MAX , B[ isThere[i] ] ) ; } } int can(int M, int K[]) { m = M ; untitled.clear() ; bool cantAlready = false ; lp(i,0,m) { int x = K[i]; int l = find(x,1); int r = find(x,0) ; if( r == -1 ) cantAlready = true ; untitled.pb( mkt( l , r , x ) ) ; } m = (int)( untitled.sz ) ; if( cantAlready ) return 0 ; return processQuery() ; }
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...