제출 #386218

#제출 시각아이디문제언어결과실행 시간메모리
386218tko919Aliens (IOI16_aliens)C++17
100 / 100
1355 ms22380 KiB
#define _USE_MATH_DEFINES #include <bits/stdc++.h> using namespace std; //template #define rep(i,a,b) for(int i=(int)(a);i<(int)(b);i++) #define ALL(v) (v).begin(),(v).end() using ll=long long int; const int inf = 0x3fffffff; const ll INF = 0x1fffffffffffffff; const double eps=1e-12; template<typename T>inline bool chmax(T& a,T b){if(a<b){a=b;return 1;}return 0;} template<typename T>inline bool chmin(T& a,T b){if(a>b){a=b;return 1;}return 0;} //end struct CHT{ int n; vector<ll> xs,p,q; vector<bool> used; CHT(const vector<ll>& ps){ n=1; while(n<(int)ps.size())n<<=1; used.assign(4*n,0); xs.resize(4*n,inf); p.resize(4*n); q.resize(4*n); rep(i,0,ps.size())xs[i]=ps[i]; } void add(ll a,ll b,int k=0,int l=0,int r=-1){ if(r==-1)r=n; while(r-l>0){ int m=(l+r)>>1; if(!used[k]){ p[k]=a; q[k]=b; used[k]=1; return; } ll lx=xs[l],mx=xs[m],rx=xs[r-1]; ll pk=p[k],qk=q[k]; bool lb=(a*lx+b<pk*lx+qk); bool mid=(a*mx+b<pk*mx+qk); bool rb=(a*rx+b<pk*rx+qk); if(lb&&rb){p[k]=a; q[k]=b; return;} if(!lb&&!rb)return; if(mid){swap(p[k],a); swap(q[k],b);} if(lb!=mid){k=2*k+1; r=m;} else{k=2*k+2; l=m;} } } void add_segment(ll a,ll b,int l,int r){ ll l0=l+n,r0=r+n,s0=l,t0=r,sz=1; while(l0<r0){ if(r0&1){r0--; t0-=sz; add(a,b,r0-1,t0,t0+sz);} if(l0&1){add(a,b,l0-1,s0,s0+sz); l0++; s0+=sz;} l0>>=1; r0>>=1; sz<<=1; } } pair<ll,ll> query(int i){ int k=i+n-1; ll ami=-1,x=xs[i],s=INF; if(used[k]){ s=p[k]*x+q[k]; ami=p[k]; } while(k){ k=(k-1)>>1; if(used[k]){ if(chmin(s,p[k]*x+q[k]))ami=p[k]; } } return {s,ami}; } }; long long take_photos(int n, int m, int k, std::vector<int> r, std::vector<int> c) { using P=pair<ll,ll>; vector<P> pos,used; rep(i,0,n){ if(r[i]>c[i])swap(r[i],c[i]); c[i]++; pos.push_back({r[i],c[i]}); } sort(ALL(pos),[](P& a,P& b){ if(a.first==b.first)return a.second>b.second; else return a.first<b.first; }); ll mx=-1; rep(i,0,n){ if(!chmax(mx,pos[i].second))continue; used.push_back(pos[i]); } n=used.size(); r.clear(); c.clear(); for(auto& [x,y]:used){ r.push_back(x); c.push_back(y); } auto get=[&](ll pena)->P{ vector<ll> ps,dp(n+10),dp2(n+10); dp[0]=dp2[0]=0; rep(i,0,n)ps.push_back(c[i]); CHT cht(ps); rep(i,0,n){ ll b=dp[i]+ll(r[i])*r[i]; if(i and c[i-1]>r[i])b-=ll(c[i-1]-r[i])*(c[i-1]-r[i]); cht.add(-2LL*r[i],b); auto [v,a]=cht.query(i); int pre=lower_bound(ALL(r),-(a/2))-r.begin(); dp[i+1]=v+ll(c[i])*c[i]+pena; dp2[i+1]=dp2[pre]+1; } return {dp[n],dp2[n]}; }; chmin(k,n); ll lb=-1,rb=1e13; while(rb-lb>1){ ll mid=(lb+rb)/2; if(get(mid).second<=k)rb=mid; else lb=mid; } auto p1=get(lb),p2=get(rb); ll x1=p1.first-lb*p1.second; ll x2=p2.first-rb*p2.second; ll s=p1.second-k,t=k-p2.second; if(t==0)return x2; else return (x1*t+x2*s)/(s+t); } /* 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; } //*/
#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...