Submission #239967

#TimeUsernameProblemLanguageResultExecution timeMemory
239967m3r8Aliens (IOI16_aliens)C++14
100 / 100
849 ms13592 KiB
#include <stdio.h>
#include <algorithm>
#include <string.h>
#include <vector>
#include <utility>
#include "aliens.h"


#define N 100100
#define M 1001000
#define ll long long
#define ii std::pair<long long,long long>
#define il std::pair<long long,int> 
#define lp std::pair<long long, long long>
#define lpp std::pair<std::pair<long long, long long>,int>

ll over[N];
int line[M];
std::vector<ii> pt;
std::vector<il> dp(N);
lpp que[N];
int ql;


ll minl(ll a, ll b){
  if(a == -1)return b;  
  if(b == -1)return a;
  return a < b ? a:b;
};

double intersect(lpp ln1, lpp ln2){
  ll f = ln2.first.second - ln1.first.second;  
  ll s = ln1.first.first - ln2.first.first;
  return (double)f/double(s);
};

void insertQue(lpp ln){
  while(ql >= 2){
    double f1 = intersect(ln,que[ql-1])+1;
    double f2 = intersect(ln,que[ql-2])+1;
    if(f2 >= f1){
      ql--;  
    }else break;
  };  
  que[ql++] = ln;
};

il findQue(ll x){
  int l = 0;  
  int r = ql;
  while(l < r){
    int m = (l+r)>>1;
    ll f1 = -1;
    ll f2 = -1;
    if(m > 0){
      f1 = intersect(que[m],que[m-1])+1;  
    };
    if(m < ql-1){
      f2 = intersect(que[m],que[m+1]);  
    };
    if(m == 0 && m == ql-1){
      l = m;  
      break;
    };
    if(m == 0 && m < ql-1 && f2 >= x){
      if(f2 >= x){
        l = m;  
        break;
      }else{
        l = m+1;  
      };
    };
    if(m == ql-1 && m > 0){
      if(f1 <= x){
        l = m;  
        break;
      }else{
        r = m;  
      };
    };
    if(m > 0 && m < ql-1){
      if(f1 <= x && x <= f2){
        l = m;
        break;
      }else if(f1 > x){
        r = m;
      }else if(f2 < x){
        l = m+1;
      };  
    };
  };
  return il(que[l].first.first * x + que[l].first.second,que[l].second+1);
};

void solvecv(ll c){
  ql = 0;  
  dp[0].first = 0; 
  dp[0].second = 0;
  insertQue(lpp(lp(-2*pt[0].first,pt[0].first * pt[0].first - over[0] * over[0] + c + dp[0].first),dp[0].second));
  ll c1;
  for(int i = 1;i<pt.size();i++){
    if(over[i])c1 = over[i] + pt[i].first;
    else c1 = std::max(over[i-1],(ll)pt[i-1].second) + pt[i-1].first; 

    dp[i] = findQue(c1);
    dp[i].first += c1 * c1;
    //printf("%lld %lld %d\n",c1,dp[i].first,dp[i].second);
    insertQue(lpp(lp(-2*pt[i].first,pt[i].first * pt[i].first - over[i] * over[i] + c + dp[i].first),dp[i].second));
  };
};

ll solvebn(ll m, ll k){
  ll l = 0;  
  ll r = m * m + 1;
  ll md;
  ll kl = 1;
  ll kr = pt.size(); 

  while(l < r){
    md = (l+r)>>1ll;  
    solvecv(md);
    int tk = dp[pt.size()-1].second;
    if(tk == k){
      return dp[pt.size()-1].first - k * md;  
    };
    if(tk > k){
      l = md+1;  
      kr = tk;
    }else{
      r = md;
      kl = tk;
    };
  };
  solvecv(r+1);
  ll tm1 = dp[pt.size()-1].first - (r+1) * kl;
  solvecv(l);
  ll tm2 = dp[pt.size()-1].first - l * kr;
  ll tm3 = (tm1-tm2) / (kr-kl);
  return tm1 - (k-kl) * tm3;
};

ll take_photos(int n, int m, int k, std::vector<int> r, std::vector<int> c){
  memset(over,0,sizeof(over));
  memset(line,0,sizeof(line));
  pt.clear();

  for(int i = 0;i<n;i++){
    if(r[i] >= c[i]){
      line[c[i]] = std::max(line[c[i]],r[i]-c[i]+1);
    }else if(r[i] < c[i]){
      line[r[i]] = std::max(line[r[i]],c[i]-r[i]+1);  
    };
  };

  for(int i = 0;i<m;i++){
    if(line[i])pt.push_back(ii(i,line[i]));  
  };

  for(int i = 1;i<pt.size();i++){
    if(over[i-1] > pt[i-1].second){
      over[i] = over[i-1] + pt[i-1].first - pt[i].first;  
    }else{
      over[i] = pt[i-1].second + pt[i-1].first - pt[i].first;
    };
    if(over[i] < 0)over[i] = 0;
    //printf("pt: %d %d %d\n",pt[i].first,pt[i].second,over[i]);
  };
  over[pt.size()] = 0;
  pt.push_back({0,0});

  //printf("%d %d %d %d\n",pt.size(),pt[0].first,pt[0].second,over[0]);
  return solvebn(m,k);
};





Compilation message (stderr)

aliens.cpp: In function 'void solvecv(long long int)':
aliens.cpp:101:18: warning: comparison between signed and unsigned integer expressions [-Wsign-compare]
   for(int i = 1;i<pt.size();i++){
                 ~^~~~~~~~~~
aliens.cpp: In function 'long long int take_photos(int, int, int, std::vector<int>, std::vector<int>)':
aliens.cpp:159:18: warning: comparison between signed and unsigned integer expressions [-Wsign-compare]
   for(int i = 1;i<pt.size();i++){
                 ~^~~~~~~~~~
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...