【8.27-模拟赛】remove

题解:

代码:

#include<iostream>
#include<algorithm>
#include<cstdio>
#include<cstring>
#define int long long
using namespace std;
const int maxn=500010;
inline int read(){
	int s=0,w=1;
	char ch=getchar();
	while(ch<'0'||ch>'9'){if(ch=='-')w=-1;ch=getchar();}
	while(ch>='0'&&ch<='9'){s=s*10+ch-'0';ch=getchar();}
	return s*w;
}
int n,s[maxn],t[maxn],a[maxn],b[maxn],f[maxn];
int Abs(int x){
    if(x<0)return -x;
    return x;
}
void add1(int pos,int k){
    for(int i=pos;i<=n;i+=(i&-i))
        s[i]=min(s[i],k);
}

void add2(int pos,int k){
    pos = n - pos + 1;
    for(int i=pos;i<=n;i+=(i&-i))
        t[i]=min(t[i],k);
}

int query1(int pos){
    int re=1e18;
    for(int i=pos;i>=1;i-=(i&-i))
        re=min(re,s[i]);
    return re;
}

int query2(int pos){
    pos=n-pos+1;
    int re=1e18;
    for(int i=pos;i>=1;i-=(i&-i))
        re=min(re,t[i]);
    return re;
}

signed main(){
	#ifdef yilnr
	#else
	freopen("remove.in","r",stdin);
	freopen("remove.out","w",stdout);
	#endif
	n=read();
	for(int i=1;i<=n;++i)
		b[i]=a[i]=read();
	memset (s,127/3,sizeof(s));
	memset (t,127/3,sizeof(t));
	sort(b+1,b+1+n);
	for(int i=1;i<=n;i++)
		a[i]=lower_bound(b+1,b+1+n,a[i])-b;
    f[2]=Abs(b[a[2]]-b[a[1]]);
	f[3]=Abs(b[a[3]]-b[a[1]]);
    add1(a[3],f[2]-b[a[3]]);
	add2(a[3],f[2]+b[a[3]]);
    for(int i=4;i<=n;i++){
        f[i]=Abs(b[a[i]]-b[a[1]]);
        int tmp1=query1(a[i]);
        int tmp2=query2(a[i]);
        f[i]=min(f[i],tmp1+b[a[i]]);
        f[i]=min(f[i],tmp2-b[a[i]]);
        add1(a[i],f[i-1]-b[a[i]]);
		add2(a[i],f[i-1]+b[a[i]]);
    }
    printf("%lld
",f[n]);
    return 0;
}

  

原文地址:https://www.cnblogs.com/yelir/p/11416415.html