제출 #67058

#제출 시각아이디문제언어결과실행 시간메모리
67058moonrabbit2Aliens (IOI16_aliens)C++17
100 / 100
1524 ms204224 KiB
#include "aliens.h" #include <bits/stdc++.h> #define N 100005 #define x first #define y second using namespace std; typedef long long ll; typedef pair<ll,ll> P; int n,m; stack<P> sstk; P aa[N],a[N]; ll dp[N],use[N][2],d[N],l; ll res[N]; ll cmax;int lv,rv; struct line { ll a,b; int mn,mx; line(ll aa,ll bb){ a=aa; b=bb; mn=mx=0; } line(ll aa,ll bb,int m1,int m2){ a=aa; b=bb; mn=m1; mx=m2; } line(){a=b=mn=mx=0;} ll get(ll x){return a*x+b;} }; struct node { line a; node *l=nullptr,*r=nullptr; node(ll aa,ll bb){ a.a=aa; a.b=bb; } node(line x){ a=x; } ll get(ll x){return a.get(x);} }; struct lichao { node *root=nullptr; ll query(ll x){return query(root,1,1e6,x);} ll query(node *nd,ll l,ll r,ll x){ if(nd==nullptr) return 1e15; ll res=nd->get(x); if(cmax>res){ lv=nd->a.mn; rv=nd->a.mx; cmax=res; } else if(cmax==res){ lv=min(lv,nd->a.mn); rv=max(rv,nd->a.mx); } if(l==r) return res; ll m=(l+r)/2; if(x<=m&&nd->l!=nullptr) return min(res,query(nd->l,l,m,x)); if(x>m&&nd->r!=nullptr) return min(res,query(nd->r,m+1,r,x)); return res; } void update(ll a,ll b,int mn,int mx){line ln=line(a,b,mn,mx);update(root,1,1e6,ln);} typedef node* pnd; void update(pnd &nd,ll l,ll r,line &a){ if(nd==nullptr){ nd=new node(a); return; } if(nd->get(l)<a.get(l)&&nd->get(r)<a.get(r)) return; if(nd->get(l)>a.get(l)&&nd->get(r)>a.get(r)){ nd->a=a; return; } ll m=(l+r)/2; if(nd->get(m)>a.get(m)) swap(nd->a,a); if(nd->get(l)<a.get(l)) update(nd->r,m+1,r,a); else update(nd->l,l,m,a); } }; void solve(ll lambda) { for(int i=0;i<n;i++) dp[i]=use[i][0]=use[i][1]=0; lichao lc; for(int i=0;i<n;i++){ dp[i]=(a[0].x-a[i].y-1)*(a[0].x-a[i].y-1)+lambda; lv=rv=0; cmax=dp[i]-a[i].y*a[i].y-2*a[i].y-1-lambda; if(i>0){ ll newv=lc.query(a[i].y)+a[i].y*a[i].y+2*a[i].y+1+lambda; if(newv<dp[i]) dp[i]=newv; } lv++;rv++; use[i][0]=lv; use[i][1]=rv; lc.update(-2LL*a[i+1].x,dp[i]+d[i]+a[i+1].x*a[i+1].x-2LL*a[i+1].x,lv,rv); } } ll take_photos(int n_,int m_,int k_,vector<int> r,vector<int> c) { n=n_;m=m_;l=k_; for(int i=0;i<n;i++) aa[i]=P(min(r[i],c[i]),max(r[i],c[i])); sort(aa,aa+n); for(int i=0;i<n;i++){ while(sstk.size()&&sstk.top().x==aa[i].x) sstk.pop(); if(sstk.size()&&sstk.top().y<=aa[i].y) sstk.push(aa[i]); else if(!sstk.size()) sstk.push(aa[i]); } n=0; while(sstk.size()){ a[n++]=sstk.top(); sstk.pop(); } sort(a,a+n); for(int i=0;i<n;i++){ if(i<n-1&&a[i].y>=a[i+1].x) d[i]=-(ll)(a[i].y-a[i+1].x+1)*(ll)(a[i].y-a[i+1].x+1); } ll L=-(ll)m*m*1000,R=-L,ans=1e18; while(L<=R){ ll M=(L+R)/2; solve(M); if(use[n-1][1]>=l&&use[n-1][0]<=l) return dp[n-1]-M*l; if(use[n-1][1]<=l){ R=M-1; ans=min(ans,dp[n-1]-M*use[n-1][1]); } else L=M+1; } return ans; }
#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...