| ||||||||||
| Online Judge | Problem Set | Authors | Online Contests | User | ||||||
|---|---|---|---|---|---|---|---|---|---|---|
| Web Board Home Page F.A.Qs Statistical Charts | Current Contest Past Contests Scheduled Contests Award Contest | |||||||||
SBT+单调队列+二分+DP 63ms#include<stdio.h>
#include<iostream>
#include<algorithm>
using namespace std;
typedef long long LL;
int limit,n,N,front=0,sbtroot,l,f,a[50001],b[50001],LAST[50001],g[50001];
LL q[210001],F[50001],sB[50001],A[50001],B[50001],LEFT,RIGHT,MID;
struct node
{int a,b,id;
}na[50001],nb[50001];
struct tree
{int l,r,s;
LL key;
}sbt[100001];
int cmpa(node a,node b){return a.a>b.a;}
int cmpb(node a,node b){return a.b>b.b;}
void lr(int& x)
{int y=sbt[x].r;
if(y==0) return;
sbt[x].r=sbt[y].l;
sbt[y].l=x;
sbt[y].s=sbt[x].s;
sbt[x].s=sbt[sbt[x].l].s+sbt[sbt[x].r].s+1;
x=y;
}
void rr(int& x)
{int y=sbt[x].l;
if(y==0) return;
sbt[x].l=sbt[y].r;
sbt[y].r=x;
sbt[y].s=sbt[x].s;
sbt[x].s=sbt[sbt[x].l].s+sbt[sbt[x].r].s+1;
x=y;
}
void maintain(int& root,bool flag)
{if(!root) return;
if(flag)
{if(sbt[root].l&&sbt[sbt[root].l].l&&(!sbt[root].r||sbt[sbt[sbt[root].l].l].s>sbt[sbt[root].r].s)) rr(root);
else if(sbt[root].l&&sbt[sbt[root].l].r&&(!sbt[root].r||sbt[sbt[sbt[root].l].r].s>sbt[sbt[root].r].s)){lr(sbt[root].l);rr(root);}
else return;
}
else
{if(sbt[root].r&&sbt[sbt[root].r].r&&(!sbt[root].l||sbt[sbt[sbt[root].r].r].s>sbt[sbt[root].l].s)) lr(root);
else if(sbt[root].r&&sbt[sbt[root].r].l&&(!sbt[root].l||sbt[sbt[sbt[root].r].l].s>sbt[sbt[root].l].s)){rr(sbt[root].r);lr(root);}
else return;
}
maintain(sbt[root].l,true);
maintain(sbt[root].r,false);
maintain(root,true);
maintain(root,false);
}
void Insert(int& root,LL x)
{if(!root)
{root=++front;
sbt[root].key=x;
sbt[root].s=1;
}
else
{++sbt[root].s;
Insert(x<=sbt[root].key?sbt[root].l:sbt[root].r,x);
maintain(root,x<=sbt[root].key);
}
}
int Delete(int& root,LL x)
{--sbt[root].s;
if(x==sbt[root].key||(x<sbt[root].key&&!sbt[root].l)||(x>sbt[root].key&&!sbt[root].r))
{LL k=sbt[root].key;
if(!sbt[root].l) root=sbt[root].r;
else if(!sbt[root].r) root=sbt[root].l;
else sbt[root].key=Delete(sbt[root].r,-1);
return k;
}
else return Delete(x<=sbt[root].key?sbt[root].l:sbt[root].r,x);
}
LL find_min(int root)
{if(!root) return 2147000000000000ll;
if(sbt[root].l!=0) return find_min(sbt[root].l);
return sbt[root].key;
}
bool work(LL L)
{int i,t;
g[1]=1;
for(i=2;i<=n;i++)
{g[i]=g[i-1];
while(sB[i]-sB[g[i]-1]>L) g[i]++;
}
for(i=1;i<=n;i++)
{F[i]=F[i-1]+A[i];
t=i-1;
while(f>l&&A[q[f]]<=A[i])
{Delete(sbtroot,A[t]+F[q[f]]);
t=q[f];
f--;
}
if(f>l&&A[i]>A[t]){Delete(sbtroot,F[q[f]]+A[t]);Insert(sbtroot,F[q[f]]+A[i]);}
if(A[i-1]>A[i])
{q[++f]=i-1;
Insert(sbtroot,A[i]+F[i-1]);
}
while(f>l&&sB[i]-sB[q[l+1]]>L)
{if(l==f-1) Delete(sbtroot,A[i]+F[q[l+1]]);
else Delete(sbtroot,A[q[l+2]]+F[q[l+1]]);
l++;
}
F[i]=min(F[i],find_min(sbtroot));
if(f>l&&q[l+1]!=g[i]-1) F[i]=min(F[i],F[g[i]-1]+A[q[l+1]]);
if(f<=l) F[i]=min(F[i],F[g[i]-1]+A[i]);
}
return F[n]<=limit;
}
void work_AB()
{int i,j,now,last,first;
for(i=1;i<=n;i++)
{na[i].a=a[i];
na[i].b=b[i];
na[i].id=i;
nb[i]=na[i];
RIGHT+=b[i];
}
sort(na+1,na+n+1,cmpa);
sort(nb+1,nb+n+1,cmpb);
now=last=1;
for(i=1;i<=n;i++)
{if(nb[i].b>na[now].a) LAST[nb[i].id]=0;
else
{while(l<=n&&nb[i].b<=na[now].a)
{last=max(last,na[now].id);
now++;
}
now--;
LAST[nb[i].id]=last;
}
}
N=0;
first=last=1;
for(i=1;i<=n;i++)
{last=max(last,LAST[i]);
if(i==last)
{N++;
for(j=first;j<=i;j++)
{A[N]=max(A[N],(LL)a[j]);
B[N]+=b[j];
}
first=last=i+1;
LEFT=max(LEFT,B[N]-1);
}
}
for(i=1;i<=N;i++) sB[i]=sB[i-1]+B[i];
n=N;
}
void work_ans()
{while(LEFT+1<RIGHT)
{MID=(LEFT+RIGHT)/2;
if(work(MID)) RIGHT=MID;
else LEFT=MID;
}
}
int main()
{cin>>n>>limit;
int i;
for(i=1;i<=n;i++) scanf("%d%d",&a[i],&b[i]);
work_AB();
work_ans();
cout<<RIGHT;
return 0;
}
Followed by: Post your reply here: |
All Rights Reserved 2003-2013 Ying Fuchen,Xu Pengcheng,Xie Di
Any problem, Please Contact Administrator