Submission #774847

#TimeUsernameProblemLanguageResultExecution timeMemory
774847ngraceTeams (IOI15_teams)C++14
0 / 100
2987 ms524288 KiB
#include "teams.h" #include <bits/stdc++.h> using namespace std; #define v vector #define ii pair<int,int> #define fi first #define se second struct node{ node* l; node* r; int sum; node(int val){ l=nullptr; r=nullptr; sum=val; } node(node* lll, node* rr){ l=lll; r=rr; sum=l->sum + r->sum; } }; node* build(int l, int r){ if(l==r) return new node(0); int m=(l+r)/2; return new node(build(l,m), build(m+1,r)); } node* update(node* cur, int l, int r, int tar){ if(l==r) return new node(cur->sum+1); int m=(l+r)/2; if(tar<=m) return new node(update(cur->l, l, m, tar), cur->r); return new node(cur->l, update(cur->r, m+1, r, tar)); } int query(node* cur, int l, int r, int ql){ if(ql<=l) return cur->sum; int m=(l+r)/2, ret=0; if(ql<=m) ret += query(cur->l, l, m, ql); ret += query(cur->r, m+1, r, ql); return ret; } int binSearchQuery(node* curl, node* curr, int l, int r, int num){ if(l==r) return l; int m=(l+r)/2; int amount = curr->r->sum - curl->r->sum; //cout<<l<<" "<<r<<" "<<num<<" "<<amount<<endl; if(amount >= num) return binSearchQuery(curl->r, curr->r, m+1, r, num); return binSearchQuery(curl->l, curr->l, l,m, num - amount); } int n; v<ii> points; v<node*> roots; int getRect(int x1, int x2, int y){ ii p1 = {x1, -1}, p2 = {x2+1, -1}; int ind1 = distance(points.begin(), lower_bound(points.begin(), points.end(), p1)); int ind2 = distance(points.begin(), lower_bound(points.begin(), points.end(), p2)); return query(roots[ind2], 1, n, y) - query(roots[ind1], 1, n, y); } int getSplit(int x1, int x2, int num){ ii p1 = {x1, -1}, p2 = {x2+1, -1}; int ind1 = distance(points.begin(), lower_bound(points.begin(), points.end(), p1)); int ind2 = distance(points.begin(), lower_bound(points.begin(), points.end(), p2)); return binSearchQuery(roots[ind1], roots[ind2], 1, n, num); } void init(int N, int A[], int B[]) { n=N; for(int i=0; i<n; i++) points.push_back({A[i], B[i]}); roots.push_back(build(1,n)); sort(points.begin(), points.end()); for(ii it:points) roots.push_back(update(roots.back(), 1, n, it.se)); } int cnt=0; int can(int M, int K[]) { sort(K, K+M); if(M>300){ priority_queue<ii> pq; int j=0; for(int i=0; i<M; i++){ while(j<n && points[j].fi<=K[i]){ pq.push({-points[j].se, points[j].fi}); j++; } while(pq.size()>0 && -pq.top().fi<K[i]) pq.pop(); if(pq.size()<K[i]) return 0; for(int k=0; k<K[i]; k++) pq.pop(); } return 1; } v<int> dp(M); set<int> opt; priority_queue<pair<int,ii>> pq; for(int i=0; i<M; i++){ dp[i] = getRect(0, K[i], K[i]) - K[i]; while(pq.size()>0 && pq.top().fi<=i){ int j1=pq.top().se.fi; int j2=pq.top().se.se; pq.pop(); if(opt.find(j1)==opt.end() || opt.find(j2)==opt.end()) continue; opt.erase(j2); auto it = opt.lower_bound(j2); if(it==opt.end()) continue; j2 = *it; int l=j2+1, r=M; while(l<r){ int m=(l+r)/2; int amount = (K[j1]==K[j2]) ? 0 : getRect(K[j1]+1, K[j2], K[l]); if(dp[j2] - dp[j1] >= amount) r=m; else l=m+1; } int k = (K[j1]==K[j2]) ? 0 : getSplit(K[j1]+1, K[j2], dp[j2]-dp[j1]); auto it2 = lower_bound(K, K+M, k); int l2 = distance(K, it2); assert(l2==l); pq.push({l, {j1,j2}}); } if(opt.size()>0){ auto it=opt.end(); it--; int j=*it; dp[i] = min(dp[i], dp[j] + (K[i]==K[j] ? 0 : getRect(K[j]+1, K[i], K[i])) - K[i]); } if(dp[i]<0) return 0; opt.insert(i); if(opt.size()>1){ auto it = opt.end(); it--; it--; int j1=*it; int j2=i; int l=j2+1, r=M; while(l<r){ int m=(l+r)/2; int amount = (K[j1]==K[j2]) ? 0 : getRect(K[j1]+1, K[j2], K[l]); if(dp[j2] - dp[j1] >= amount) r=m; else l=m+1; } int k = (K[j1]==K[j2]) ? 0 : getSplit(K[j1]+1, K[j2], dp[j2]-dp[j1]); auto it2 = lower_bound(K, K+M, k); int l2 = distance(K, it2); //cout<<j1<<" "<<j2<<" "<<dp[j2]-dp[j1]<<" "<<k<<" "<<getRect(K[j1]+1,K[j2],k)<<endl; assert(l2==l); pq.push({l, {j1,j2}}); } } return 1; }

Compilation message (stderr)

teams.cpp: In function 'int getRect(int, int, int)':
teams.cpp:57:21: warning: conversion from 'std::__iterator_traits<__gnu_cxx::__normal_iterator<std::pair<int, int>*, std::vector<std::pair<int, int> > >, void>::difference_type' {aka 'long int'} to 'int' may change value [-Wconversion]
   57 |  int ind1 = distance(points.begin(), lower_bound(points.begin(), points.end(), p1));
      |             ~~~~~~~~^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
teams.cpp:58:21: warning: conversion from 'std::__iterator_traits<__gnu_cxx::__normal_iterator<std::pair<int, int>*, std::vector<std::pair<int, int> > >, void>::difference_type' {aka 'long int'} to 'int' may change value [-Wconversion]
   58 |  int ind2 = distance(points.begin(), lower_bound(points.begin(), points.end(), p2));
      |             ~~~~~~~~^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
teams.cpp: In function 'int getSplit(int, int, int)':
teams.cpp:63:21: warning: conversion from 'std::__iterator_traits<__gnu_cxx::__normal_iterator<std::pair<int, int>*, std::vector<std::pair<int, int> > >, void>::difference_type' {aka 'long int'} to 'int' may change value [-Wconversion]
   63 |  int ind1 = distance(points.begin(), lower_bound(points.begin(), points.end(), p1));
      |             ~~~~~~~~^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
teams.cpp:64:21: warning: conversion from 'std::__iterator_traits<__gnu_cxx::__normal_iterator<std::pair<int, int>*, std::vector<std::pair<int, int> > >, void>::difference_type' {aka 'long int'} to 'int' may change value [-Wconversion]
   64 |  int ind2 = distance(points.begin(), lower_bound(points.begin(), points.end(), p2));
      |             ~~~~~~~~^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
teams.cpp: In function 'int can(int, int*)':
teams.cpp:90:16: warning: comparison of integer expressions of different signedness: 'std::priority_queue<std::pair<int, int> >::size_type' {aka 'long unsigned int'} and 'int' [-Wsign-compare]
   90 |    if(pq.size()<K[i]) return 0;
      |       ~~~~~~~~~^~~~~
teams.cpp:120:21: warning: conversion from 'std::iterator_traits<int*>::difference_type' {aka 'long int'} to 'int' may change value [-Wconversion]
  120 |    int l2 = distance(K, it2);
      |             ~~~~~~~~^~~~~~~~
teams.cpp:150:21: warning: conversion from 'std::iterator_traits<int*>::difference_type' {aka 'long int'} to 'int' may change value [-Wconversion]
  150 |    int l2 = distance(K, it2);
      |             ~~~~~~~~^~~~~~~~
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...