题意
给你一个排列,然后先分成非空的两段(一段是前缀,一段是后缀),然后每挪一个元素到另一端都有一个花费,问最少花费使得前面一段严格小于后面一段
题解
这种题读完题目就应该知道是数据结构,分成两段可以考虑枚举前面一段的最大的数
然后就是要考虑在哪里切,线段树维护分割线
一开始所有数都对该数以后的分割线都有花费(包含就要被挪出去)
后来包含的就不用被挪出去,不包含的还要有花费(分割线不包含的花费增加)
这样把所有分割线的情况考虑了就可以了,线段树维护上述操作
代码
#include <set>
#include <map>
#include <cmath>
#include <ctime>
#include <deque>
#include <queue>
#include <stack>
#include <bitset>
#include <cstdio>
#include <vector>
#include <cstdlib>
#include <cstring>
#include <climits>
#include <complex>
#include <iostream>
#include <algorithm>
#define fi first
#define se second
#define MP make_pair
#define PB push_back
#define dmp(x) cout << (x) << endl;
using namespace std;
typedef unsigned long long ull;
typedef long long ll;
typedef pair<ll,ll> pii;
const ll N = 1000010;
const ll mod = 998244353;
const ll inf = 1e15;
inline ll read()
{
ll p=0; ll f=1; char ch=getchar();
while(ch<'0' || ch>'9'){if(ch=='-') f*=-1; ch=getchar();}
while(ch>='0' && ch<='9'){p=p*10+ch-'0'; ch=getchar();}
return p*f;
}
ll lc[N<<1],rc[N<<1],lazy[N<<1],c[N<<1]; ll rt,tot;
void build(ll &u,ll L,ll R)
{
if(!u) u = ++tot;
if(L==R){c[u] = 0; return ;}
ll mid = (L+R)>>1;
build(lc[u],L,mid);
build(rc[u],mid+1,R);
c[u] = min(c[lc[u]] , c[rc[u]]);
}
void push_down(ll u)
{
if(lazy[u])
{
lazy[lc[u]] += lazy[u];
lazy[rc[u]] += lazy[u];
c[lc[u]] += lazy[u];
c[rc[u]] += lazy[u];
lazy[u] = 0;
}
}
void chg(ll u,ll L,ll R,ll l,ll r,ll cc)
{
if(L==l && R==r){lazy[u] += cc; c[u] +=cc; return ;}
push_down(u);
ll mid = (L+R)>>1;
if(r<=mid) chg(lc[u],L,mid,l,r,cc);
else if(l>mid) chg(rc[u],mid+1,R,l,r,cc);
else
{
chg(lc[u],L,mid,l,mid,cc);
chg(rc[u],mid+1,R,mid+1,r,cc);
}c[u] = min(c[lc[u]] , c[rc[u]]);
}
ll p[N],a[N],pos[N];
int main()
{
ll n; cin >> n; rt=tot=0; build(rt,1,n-1);
for(ll i=1;i<=n;i++) cin >> p[i],pos[p[i]] = i;
for(ll i=1;i<=n;i++) cin >> a[i];
for(ll i=1;i<n;i++) chg(rt,1,n-1,i,n-1,a[i]);
ll ans = c[1];
for(ll i=1;i<=n;i++)
{
if(pos[i] != n) chg(rt,1,n-1,pos[i],n-1,-a[pos[i]]);
if(pos[i] != 1) chg(rt,1,n-1,1,pos[i]-1,a[pos[i]]);
ans = min(ans , c[1]);
}
return printf("%lld\n",ans),0;
}