| 记录编号 |
390429 |
评测结果 |
AAAAAAAAAAAAAAAAAAAA |
| 题目名称 |
1859.[国家集训队2011]拆迁队 |
最终得分 |
100 |
| 用户昵称 |
_Itachi |
是否通过 |
通过 |
| 代码语言 |
C++ |
运行时间 |
0.946 s |
| 提交时间 |
2017-04-03 06:18:17 |
内存使用 |
5.25 MiB |
显示代码纯文本
#include<stdio.h>
#include<string.h>
#include<algorithm>
using namespace std;
char cc;inline void R_int(int &x){
while(cc=getchar(),cc<'!');x=cc-48;
while(cc=getchar(),cc>'!')x=x*10+cc-48;
}
#define LL long long
const int maxn=100005,INF=0x3f3f3f3f;
struct Rabit_tree{int to,next;}e[maxn];
int n,g[maxn],st[maxn],cot,num[maxn];LL A[maxn],B[maxn],f[maxn];
void Rabit_in(){
R_int(n);int i,x;
for(i=1;i<=n;i++)R_int(x),A[i]=x;
for(i=1;i<=n;i++)R_int(x),B[i]=x;
}
void Rabit_bl(){
int i,j;memset(g,-1,sizeof(g));f[0]=g[0]=0;
for(i=1;i<=n;i++)
for(j=0;j<i;j++)
if(i-j<=A[i]-A[j]&&g[j]>=0){
if(g[j]+1>g[i])g[i]=g[j]+1,
f[i]=f[j]+A[i]+B[i]+(i-j)*1ll*(i-j-1)/2ll+A[j]*1ll*(i-j-1);
else if(g[j]+1==g[i])
f[i]=min(f[i],f[j]+A[i]+B[i]+(i-j)*1ll*(i-j-1)/2ll+A[j]*1ll*(i-j-1));
}
int ans1=0;LL ans2;
for(i=1;i<=n;i++)
if(g[i]>ans1)ans1=g[i],ans2=f[i]+A[i]*1ll*(n-i)+(n-i+1)*1ll*(n-i)/2ll;
else if(g[i]==ans1)ans2=min(ans2,f[i]+A[i]*1ll*(n-i)+(n-i+1)*1ll*(n-i)/2ll);
printf("%d %lld\n",ans1,ans2);
}
int c[maxn],head[maxn],len=1;
void Set(int prt,int son){
e[++len].to=son,e[len].next=head[prt],head[prt]=len;
}
void Add(int i,int x){
for(;i<=cot;i+=i&(-i))c[i]=max(c[i],x);
}
int Get(int i){
int res=-INF;for(;i;i-=i&(-i))res=max(res,c[i]);return res;
}
#define to e[i].to
void Rabit_sb(){
int i,rt,ans1=0;LL ans2=1e20;
for(i=0;i<=n;i++)st[++cot]=A[i]-i;
sort(st+1,st+cot+1);cot=unique(st+1,st+cot+1)-st-1;
for(i=0;i<=n;i++)num[i]=lower_bound(st+1,st+cot+1,A[i]-i)-st;
for(i=1;i<=cot;i++)c[i]=-INF;
Add(num[0],g[0]),Set(g[0],0);
for(rt=1;rt<=n;rt++){
g[rt]=Get(num[rt])+1,Add(num[rt],g[rt]),f[rt]=1ll<<50;
if(g[rt]>0){
for(i=head[g[rt]-1];i;i=e[i].next)
if(num[rt]>=num[to])
f[rt]=min(f[rt],
f[to]+A[rt]+B[rt]+(rt-to)*1ll*(rt-to-1)/2ll+A[to]*1ll*(rt-to-1));
Set(g[rt],rt);
}
}
ans1=Get(cot);
for(i=head[ans1];i;i=e[i].next)
ans2=min(ans2,f[to]+A[to]*1ll*(n-to)+(n-to+1)*1ll*(n-to)/2ll);
printf("%d %lld\n",ans1,ans2);
}
int main(){
freopen("lanxisi.in","r",stdin);freopen("lanxisi.out","w",stdout);
Rabit_in();//Rabit_bl();
Rabit_sb();
fclose(stdin);fclose(stdout);return 0;
}