Submission #861467

#TimeUsernameProblemLanguageResultExecution timeMemory
861467tosivanmakAliens (IOI16_aliens)C++17
100 / 100
455 ms23836 KiB
#include<bits/stdc++.h>
using namespace std;
#define ll long long
#define ld long double


struct LINE{
  ld m, c, ocpt; ll chosennumbers;
  bool operator !=(const LINE& l)const{
    return l.m!=m||l.c!=c||l.ocpt!=ocpt||l.chosennumbers!=chosennumbers;
  }
};
deque<LINE>q;
ll outc[100005],outr[100005],outn,outm,outk,getmin[1000005];
pair<ld,ll> dp[1000005];
vector<pair<ll,ll> >need;
pair<ld,ld> int_pt(LINE a, LINE b){
  ld x=(b.c-a.c)/(a.m-b.m);
  ld y=a.m*x+a.c;
  return {x,y};
}
void insert(LINE l){
    while(!q.empty()&&int_pt(l,q.back()).first<=q.back().ocpt){
      q.pop_back();
    }
    l.ocpt=int_pt(q.back(),l).first;
    q.push_back(l);
}
pair<ld,ll> qry(ld x){
  LINE store={-1e18,-1e18,-1e18,-10000000000000},comp=store;
  while(!q.empty()&&q.front().ocpt<=x){
    store=q.front();
    q.pop_front();
  }
  if(store!=comp){
    q.push_front(store);
  }
  LINE ans=q.front();
  return {ans.m*x+ans.c,ans.chosennumbers};
}
bool ck(ld lambda){
    // I から j まで の一番小さい 解決の後 は I−1 が 解決 すること出来るかな
    // from i to j (i-smallest+1)*(i-smallest+1)+dp[minimum-1]
    // i^2 - i*smallest + i + smallest^2 - smallest + i -smallest +1 +dp[i-1]
    // i^2 + 2*i + smallest^2 - 2* smallest + 1 + dp[i-1] - smallest*i 
    // same for all: i^2 + 2*i
    // slope: -smallest (x = i)
    // constant: smallest^2 - 2*smallest + 1 + dp[i-1]
    // もしかしたら、小さいの数は変わってば、dp[0]が使えます
    // じゃないなら、slope が入ります
    // 一番小さいから、 Alienの cost は +cost です
    for(int i=0;i<need.size();i++){
          // (need[i].first-(cur-1))^2
          // need[i].first^2 - 2*(cur-1)*need[i].first + (cur-1)^2
          // slope: -2*(cur-1)
          // x: need[i].first
          // constant: (cur-1)^2 - (need[i+1].second-need[i].first+1)^2 only if need[i+1].second-need[i].first>=0 + dp[cur]
          // always part: need[i].first^2
          if(i==0){
            dp[i]={(need[i].first-need[i].second+1)*(need[i].first-need[i].second+1)+lambda,1};
              if(i!=need.size()-1){
            //  insert part
            ld slo=-2*(need[i+1].second-1);
            ld con=(need[i+1].second-1)*(need[i+1].second-1);
           if(need[i].first-need[i+1].second>=0){
              con-=(need[i].first-need[i+1].second+1)*(need[i].first-need[i+1].second+1);
            }
            con+=dp[i].first;
            q.push_back({slo,con,-1e18,dp[i].second});
         }
          }
          else{
          pair<ld,ll> take=qry((ld)need[i].first);
         take.first= take.first+lambda+need[i].first*need[i].first;
         take.second++;
         dp[i]=take;
         pair<ld,ll>anotheroption={(need[i].first-need[0].second+1)*(need[i].first-need[0].second+1)+lambda,1};
         dp[i]=min(dp[i],anotheroption);
         if(i!=need.size()-1){
            //  insert part
            ld slo=-2*(need[i+1].second-1);
            ld con=(need[i+1].second-1)*(need[i+1].second-1);
            if(need[i].first-need[i+1].second>=0){
              con-=(need[i].first-need[i+1].second+1)*(need[i].first-need[i+1].second+1);
            }
            con+=dp[i].first;
            insert({slo,con,0,dp[i].second});
         }
          }
    }
    while(q.size()){
      q.pop_back();
    }
    return dp[need.size()-1].second<=outk;
    // dp[need.size()-1].
}

ld Aliens(){
   ld l=0,r=(ld)1000000*(ld)1000000;
   while(r-l>=1e-4){
     ld mid=(l+r)/2;
    //  minimum grids
    // cout<<mid<<'\n';
     if(ck(mid)){
        r=mid;
     }
     else{
       l=mid;
     }
   }
   l=r;
   ck(l);
  //  cout<<l<<" ";
  //  cout<<dp[need.size()-1].first-l*(ld)outk<<"\n";
   return dp[need.size()-1].first-l*(ld)outk;
}

ll take_photos(int n, int m, int k, std::vector<int> r, std::vector<int> c){
  //convert back to array 1-based and cell 1-based
  outn=n,outm=m,outk=k;
    int storer[n+5], storec[n+5];
    for(int i=1;i<=m;i++){
      getmin[i]=1e18;
    }
    vector<ll>lol;
    for(int i=1;i<=n;i++){
      storer[i]=r[i-1]+1;
      storec[i]=c[i-1]+1;
      outc[i]=storec[i];
      outr[i]=storer[i];
      getmin[max(outc[i],outr[i])]=min(getmin[max(outc[i],outr[i])],min(outc[i],outr[i]));
      lol.push_back(max(outc[i],outr[i]));
    }
    outn=n,outm=m,outk=k;
  // solve the q find for all m points the minimum size of the square needed
  // 
  // need push backs id then occupy pt
  sort(lol.begin(),lol.end());
   need.push_back({lol[0],getmin[lol[0]]});
    for(int i=1;i<lol.size();i++){
      if(lol[i]==lol[i-1]){
        continue;
      }
        while(need.size()){
          if(need.back().second>=getmin[lol[i]]){
            need.pop_back();
          }
          else{
            break;
          }
        }
        if(getmin[lol[i]]!=1e18){
        need.push_back({lol[i],getmin[lol[i]]});
        }
    }
    outk=min(outk,(ll)need.size());
    // for(auto u: lol){
    //   cout<<u<<" ";
    // }
    // cout<<"\n";
    // for(auto u: need){
    //   cout<<u.first<<" "<<u.second<<"\n";
    // }
    ld ans=Aliens();
    //  cout<<ans<<"\n";
    //  cout<<dp[need.size()-1].second<<"\n";
    //  cout<<outk<<'\n';
    // for(int i=0;i<need.size()-1;i++){
    //   cout<<dp[i].first<<"\n";
    // }
     return (ll)round(ans);

}

// #ifndef ONLINE_JUDGE
//      int main() {
//     int n, m, k;
//     assert(3 == scanf("%d %d %d", &n, &m, &k));
//     std::vector<int> r(n), c(n);
//     for (int i = 0; i < n; i++) {
//         assert(2 == scanf("%d %d", &r[i], &c[i]));
//     }
//     long long ans = take_photos(n, m, k, r, c);
    
    
//     printf("%lld\n", ans);
//     return 0;
// }
// #endif

Compilation message (stderr)

aliens.cpp: In function 'bool ck(long double)':
aliens.cpp:52:18: warning: comparison of integer expressions of different signedness: 'int' and 'std::vector<std::pair<long long int, long long int> >::size_type' {aka 'long unsigned int'} [-Wsign-compare]
   52 |     for(int i=0;i<need.size();i++){
      |                 ~^~~~~~~~~~~~
aliens.cpp:61:19: warning: comparison of integer expressions of different signedness: 'int' and 'std::vector<std::pair<long long int, long long int> >::size_type' {aka 'long unsigned int'} [-Wsign-compare]
   61 |               if(i!=need.size()-1){
      |                  ~^~~~~~~~~~~~~~~
aliens.cpp:79:14: warning: comparison of integer expressions of different signedness: 'int' and 'std::vector<std::pair<long long int, long long int> >::size_type' {aka 'long unsigned int'} [-Wsign-compare]
   79 |          if(i!=need.size()-1){
      |             ~^~~~~~~~~~~~~~~
aliens.cpp: In function 'long long int take_photos(int, int, int, std::vector<int>, std::vector<int>)':
aliens.cpp:140:18: warning: comparison of integer expressions of different signedness: 'int' and 'std::vector<long long int>::size_type' {aka 'long unsigned int'} [-Wsign-compare]
  140 |     for(int i=1;i<lol.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...