제출 #224867

#제출 시각아이디문제언어결과실행 시간메모리
224867urd05Aliens (IOI16_aliens)C++14
100 / 100
155 ms8696 KiB
#include <bits/stdc++.h> using namespace std; typedef pair<long long,long long> P; P arr[100000]; P temp[100000]; long long dp[100005]; //dp[i][j] : minimum grid to fill if we should take a picture unitl i-th place with j pictures. const long long INF=1e18; long long n,m,k; int sz=0; int ind=0; struct Line { long long a,b; }; struct Fraction { long long up,down; }; Fraction cross(Line one,Line two) { if (one.a<two.a) { swap(one,two); } return {two.b-one.b,one.a-two.a}; } bool cmp(Fraction one,Fraction two) { __int128 ou=one.up; __int128 od=one.down; __int128 tu=two.up; __int128 td=two.down; return ou*td<tu*od; } Line line[100513]; void insert(Line l) { if (sz>=1&&line[sz-1].a==l.a) { if (l.b>line[sz-1].b) { line[sz-1]=l; } return; } while (sz>1) { Fraction before=cross(line[sz-2],line[sz-1]); Fraction now=cross(line[sz-1],l); if (cmp(before,now)) { break; } sz--; } line[sz++]=l; } long long cost(int l,int r) { long long minus=0; if (l!=0&&arr[l-1].second-arr[l].first+2>0) { minus=(arr[l-1].second-arr[l].first+2)*(arr[l-1].second-arr[l].first+2); } long long ret=(arr[r].second-arr[l].first+2)*(arr[r].second-arr[l].first+2); ret-=minus; return ret*2; } long long value; int cut; void getans(long long pen) { sz=0; ind=0; for(int i=0;i<n;i++) { if (i>0) { long long minus=0; if (arr[i-1].second-arr[i].first+2>0) { minus=(arr[i-1].second-arr[i].first+2)*(arr[i-1].second-arr[i].first+2); } insert({-4*arr[i].first,2*arr[i].first*arr[i].first-8*arr[i].first-minus*2+dp[i-1]+pen}); } else { insert({-4*arr[i].first,2*arr[i].first*arr[i].first-8*arr[i].first+pen}); } while (ind+1<sz&&cmp(cross(line[ind],line[ind+1]),{arr[i].second,1})) { ind++; } long long val; if (ind>=sz) { val=INF; } else { val=line[ind].a*arr[i].second+line[ind].b+2*(arr[i].second+2)*(arr[i].second+2); } dp[i]=val; } int now=n-1; int cnt=0; while (now!=-1) { for(int i=now;i>=0;i--) { long long val; if (i==0) { val=0; } else { val=dp[i-1]; } if (val+cost(i,now)+pen==dp[now]) { now=i-1; cnt++; break; } if (i==0) { printf(".\n"); now=-1; } } } value=dp[n-1]; cut=cnt; } bool comp(P a,P b) { if (a.second==b.second) { return a.first<b.first; } return a.second<b.second; } long long take_photos(int nn,int mm,int kk,vector<int> r,vector<int> c) { n=nn; m=mm; k=kk; for(int i=0;i<n;i++) { if (r[i]>c[i]) { swap(r[i],c[i]); } temp[i]=P(2*r[i]+1,2*c[i]+1); } sort(temp,temp+n,comp); int s=0; long long mini=1e8; for(int i=n-1;i>=0;i--) { if (temp[i].first<mini) { arr[s++]=temp[i]; } mini=min(mini,temp[i].first); } n=s; reverse(arr,arr+n); long long lo=-1; long long hi=8*m*m+13; //(lo,hi] while (lo+1<hi) { long long mid=lo+(hi-lo)/2; getans(2*mid+1); if (k<=cut) { lo=mid; } else { hi=mid; } } getans(2*hi); if ((value-2*k*hi)%8!=0) { return r[-1000000]; } return (value-2*k*hi)/8; }
#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...