F. Strange Function(Educational Codeforces Round 85 (Rated for Div. 2))

传送门

题意:给两个数组ai和bi,删除ai中元素需要花费pi的代价,bi是一个严格递增序列,问你将ai删为bi的最小1花费代价。

题解:开一个dp数组代表bi匹配到当前位的最小代价,由于bi是一个严格递增序列,所以ai对应唯一一个bi的匹配位置,所以用dp降为一维,dp[k]由dp[k-1]推出,即删除大于bi[k-1]的数,同时由于要求最小代价所以还应将小于等于bi[k-1]的负数也删除,同时dp[k]如果已经被匹配了,需要将dp[k]的右限更新(原本dp[k]的右限是本身),对于需要计数的两个数可以用树状数组+两个数组维护,具体看代码,最后就是bi[m]不一定匹配到ai的最后一位,所以还需要计算一次两个的值。

ac代码:

#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#define ll long long
#define fo(n) for(int i=1;i<=n;i++)
#define fol(n) for(int i=n;i>=1;i--)
#define foj(i,n) for(int j=i;j<=n;j++)
#define fok(i,j) for(int k=i;k<=j;k++)
#define oui(i) printf("%d\n",i)
#define oul(i) printf("%lld\n",i)
#define sc(n) scanf("%d",&n)
#define scl(n) scanf("%lld",&n)
#define mid ((l+r)>>1)
using namespace std;
int read(){
    char c;int x=0,y=1;while(c=getchar(),(c<'0'||c>'9')&&c!='-');
    if(c=='-') y=-1;else x=c-'0';while(c=getchar(),c>='0'&&c<='9')
        x=x*10+c-'0';return x*y;
}
const int maxn=5e5+10;
const int mod=1e9+7;
const ll inf=-1e18;
int ai[maxn],bi[maxn],wi[maxn],pi[maxn];
ll dp[maxn],del[maxn],de[maxn];
int dp1[maxn];
struct node {
    ll tree[maxn];
    int lowbit(int x){return x&(-x);}
    void add(int x,ll va){
        while(x0) ans+=tree[x],x-=lowbit(x);
        return ans;
    }
}A,B;
int main( ){
    int n=read();
    dp[0]=bi[0]=dp1[0]=de[0]=del[0]=0;
    for(int a=1;a<=n;a++) ai[a]=read(),wi[a]=-1;
    for(int a=1;a<=n;a++) {pi[a]=read();}
    int m=read();
    for(int a=1;a<=m;a++){bi[a]=read();wi[bi[a]]=a;dp[a]=inf,del[a]=de[a]=0;}
    ll su=0;
    for(int a=1;a<=n;a++) {
        int k=wi[ai[a]];
        if(k!=-1&&dp[k-1]!=inf){
            ll ans=su-A.query(bi[k-1])-de[dp1[k-1]],ans2=0,ans3=0;
            ll ans1=B.query(bi[k-1])-del[dp1[k-1]];
            if(dp[k]!=inf) {
                ans2 =su-A.query(bi[k]) - de[dp1[k]];
                ans3=B.query(bi[k])-del[dp1[k]]+min(0,pi[a]);
            }
            if(dp[k]==inf||dp[k-1]+ans+ans1

 

你可能感兴趣的:(ACM,数据结构,算法)