[HNOI2002]营业额统计

题目点我

题目大意:给出含N个数的序列,定义第i个数的权为其与前i-1个数的最小差值,求权和

平衡树模板题,但是此题有相当巧妙的线性表解法。

对N个数排序并建立双向链表,依照从第N个数开始,检查其在链表中的前驱与后继,计入权后删去,最后输出即为权和。

//营业额统计 线性表 
#include<cstdio>
#define min(a,b) a<b?a:b
#define N 1000000
int n,input[N],ins[N],num[N],id[N],last[N],next[N];
int fabs(int i){return i>0?i:-i;}
int Quick(int i,int j){
int k=ins[i],t=id[i];
while(i<j){
while(i<j && ins[j]>=k) j--;
ins[i]=ins[j];id[i]=id[j];
while(i<j && ins[i]<=k) i++;
ins[j]=ins[i];id[j]=id[i];
}
ins[i]=k;id[i]=t;
return i;
}
void Sort(int i,int j){
if(i<j){
int k=Quick(i,j);
Sort(i,k-1);
Sort(k+1,j);
}
}
int main(){
long res;
scanf("%d",&n);
for(int i=1;i<=n;i++){
scanf("%d",&ins[i]);
input[i]=ins[i];
id[i]=i;
}
Sort(1,n);
for(int i=1;i<=n;i++){
num[id[i]]=i;
last[id[i]]=id[i-1];
next[id[i]]=id[i+1];
}
res=0;
input[0]=input[n+1]=2147483647;
for(int i=n;i>1;i--){
res+=min(fabs(input[i]-input[last[i]]),fabs(input[i]-input[next[i]]));
next[last[i]]=next[i];
last[next[i]]=last[i];
}
res+=input[1];
printf("%ld\n",res);
return 0;
}



转载于:https://www.cnblogs.com/X-Kly/archive/2011/10/30/BZOJ1588.html

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值