제출 #540245

#제출 시각아이디문제언어결과실행 시간메모리
540245new_accAliens (IOI16_aliens)C++14
25 / 100
101 ms8276 KiB
#include<bits/stdc++.h>
#define fi first
#define se second
#define pitem item*
using namespace std;
typedef long long ll;
typedef vector<int> vi;
typedef vector<ll> vl;
const int M=1e6+10;
const int N=1e5+10;
const int SS=1<<20;
const int INFi=1e9;
const ll INFl=1e12;
struct f{
	ll a,b;
	int ind;
	ll operator()(ll x){
		return a*x+b;
	}
};
struct item{
	f fun;
	item *l,*r;
};
pair<ll,int> dp[N];
f nullp;
bool cmp(f a,f b,int p,int k){
	if((a(p)<b(p) and a(k)<b(k)) or (a(p)<=b(p) and a(k)<b(k)) or (a(p)<b(p) and a(k)<=b(k))) return 1;
	if(a(p)==b(p) and a(k)==b(k) and dp[a.ind].se<dp[b.ind].se) return 1;
	return 0;
}
pitem upd(pitem v,f x,int p=0,int k=SS-1){
	if(p>k) return nullptr;
	if(!v){
		v=new item;
		v->l=nullptr,v->r=nullptr,v->fun=x;
		return v;
	}
	int sr=(p+k)>>1;
	if(cmp(x,v->fun,p,sr)){
		v->r=upd(v->r,v->fun,sr+1,k);
		v->fun=x;
	}else if(cmp(x,v->fun,sr+1,k)){
		v->l=upd(v->l,v->fun,p,sr);
		v->fun=x;
	}else if(cmp(v->fun,x,p,sr))
		v->r=upd(v->r,x,sr+1,k);
	else v->l=upd(v->l,x,p,sr);
	return v;
}
f Query(pitem v,int x,int p=0,int k=SS-1){
	if(!v) return nullp;
	f pom;
	if(x<=((p+k)>>1)) pom=Query(v->l,x,p,(p+k)>>1);
	else pom=Query(v->r,x,((p+k)>>1)+1,k);
	if(cmp(v->fun,pom,x,x)) return v->fun;
	return pom;
}
void clear(pitem v){
	if(!v) return;
	clear(v->l),clear(v->r);
	delete(v);
}
int t[N],l,val[N],mini[M],mini2[M],kw[N];
ll res=INFl;
int wsp(int i){
	if(t[i]-val[i]+1>kw[i]) return INFi;
	if(val[i]>t[i]) return 0;
	return (ll)(t[i]-val[i]+1)*(ll)(t[i]-val[i]+1);
}
f func(int i){
	int w=wsp(i);
	if(w==INFi) return nullp;
	f pom;
	pom.a=-2*val[i],pom.b=dp[i].fi+(ll)val[i]*(ll)val[i]+1LL-2LL*val[i]-w;
	pom.ind=i;
	return pom;
}
bool check(ll c,int k){
	pitem v=nullptr;
	int mm=INFi;
	for(int i=1;i<=l;i++){
		mm=min(mm,mini[t[i]]);
		ll pom1=INFl;
		f curr=Query(v,t[i]);
		if(curr.b!=INFl) pom1=curr(t[i])+(ll)t[i]*(ll)t[i]+2LL*(ll)t[i]+c;
		dp[i]={(ll)(t[i]-mm+1)*(ll)(t[i]-mm+1)+c,1};	
		kw[i]=t[i]-mm+1;
		if(dp[i].fi>pom1){
			dp[i]={pom1,dp[curr.ind].se+1};
			kw[i]=t[i]-val[curr.ind]+1;
		}
		if(i!=l){
			f pom2=func(i);
			if(pom2.b!=INFl) v=upd(v,pom2);
		}
	}
	clear(v);
	if(dp[l].se<=k){
		res=dp[l].fi-(ll)k*c;
		return 1;
	}
	return 0;
}
ll take_photos(int n,int m,int k,vi r,vi c){
	nullp.a=INFi,nullp.b=INFl;
	for(int i=1;i<=m;i++) mini[i]=INFi;
	for(int i=1;i<=n;i++){
		r[i-1]++,c[i-1]++;
		if(r[i-1]>c[i-1]) swap(r[i-1],c[i-1]);
		mini[c[i-1]]=min(mini[c[i-1]],r[i-1]);
	}
	int akt=INFi;
	for(int i=m;i>=1;i--){
		mini2[i]=akt;
		akt=min(akt,mini[i]);
	}
	for(int i=1;i<=m;i++) if(mini[i]!=INFi) t[++l]=i,val[l]=mini2[i];
	ll pocz=0,kon=1000LL*1000LL*1000LL*1000LL;
	while(pocz<=kon){
		ll sr=(pocz+kon)>>1;
		if(check(sr,k)) kon=sr-1;
		else pocz=sr+1;
	}
	return res;
}
/*int main(){
	int n,m,k;
	cin>>n>>m>>k;
	vi r,c;
	for(int i=1,a,b;i<=n;i++){
		cin>>a>>b;
		r.push_back(a),c.push_back(b);
	}
	cout<<take_photos(n,m,k,r,c)<<"\n";
}*/
#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...