洛谷P1973 [NOI2011]Noi嘉年华(决策单调性)

时间:2021-12-10 08:17:20

传送门

鉴于FlashHu大佬讲的这么好(而且我根本不会)我就不再讲一遍了->传送

 //minamoto
#include<iostream>
#include<cstdio>
#include<algorithm>
#define upd(A,L,R) {cmax(A[i][j],A[k][j]+tot[L][R]);\
if(j>=tot[L][R]) cmax(A[i][j],A[k][j-tot[L][R]]);}
#define calc(y) min(x+tot[l][r]+y,Pre[l][x]+suf[r][y])
using namespace std;
#define getc() (p1==p2&&(p2=(p1=buf)+fread(buf,1,1<<21,stdin),p1==p2)?EOF:*p1++)
char buf[<<],*p1=buf,*p2=buf;
template<class T>inline bool cmax(T&a,const T&b){return a<b?a=b,:;}
template<class T>inline int min(T&a,T&b){return a<b?a:b;}
inline int read(){
#define num ch-'0'
char ch;bool flag=;int res;
while(!isdigit(ch=getc()))
(ch=='-')&&(flag=true);
for(res=num;isdigit(ch=getc());res=res*+num);
(flag)&&(res=-res);
#undef num
return res;
}
char sr[<<],z[];int C=-,Z;
inline void Ot(){fwrite(sr,,C+,stdout),C=-;}
inline void print(int x){
if(C><<)Ot();if(x<)sr[++C]=,x=-x;
while(z[++Z]=x%+,x/=);
while(sr[++C]=z[Z],--Z);sr[++C]='\n';
}
const int N=,M=,inf=0x3f3f3f3f;
int s[N],t[N],b[M],tot[M][M],Pre[M][N],suf[M][N],f[M][M];
int main(){
//freopen("testdata.in","r",stdin);
int n=read(),m=,ans;
for(int i=;i<=n;++i){
b[++m]=s[i]=read();
b[++m]=t[i]=read()+s[i];
}
sort(b+,b++m);
m=unique(b+,b++m)-b-;
for(int i=;i<=n;++i){
s[i]=lower_bound(b+,b++m,s[i])-b;
t[i]=lower_bound(b+,b++m,t[i])-b;
for(int l=;l<=s[i];++l)
for(int r=m;r>=t[i];--r) ++tot[l][r];
}
for(int i=;i<=m;++i) for(int j=;j<=n;++j)
Pre[i][j]=suf[i][j]=-inf;
for(int i=;i<=m;++i)
for(int j=;j<=tot[][i];++j)
for(int k=;k<=i;++k) upd(Pre,k,i);
for(int i=m;i;--i)
for(int j=;j<=tot[i][m];++j)
for(int k=i;k<=m;++k) upd(suf,i,k);
for(int l=;l<=m;++l)
for(int r=l+;r<=m;++r)
for(int y=n,x=;x<=n;++x){
int p0=calc(y),p1;
while(y&&p0<=(p1=calc(y-))) p0=p1,--y;
cmax(f[l][r],p0);
}
ans=;
for(int j=;j<=n;++j) cmax(ans,min(Pre[m][j],j));
print(ans);
for(int i=;i<=n;++i){
ans=;
for(int l=;l<=s[i];++l)
for(int r=m;r>=t[i];--r) cmax(ans,f[l][r]);
print(ans);
}
Ot();
return ;
}