Three displays CodeForces - 987C

点击打开链接

基于s值建立线段树

从左到右 对于i 利用线段树维护 [1,i-1] 范围内 s值比s[i]小的元素中c值最小的是多少 再从右到左跑一遍

似乎dp也可以写 只是复杂度要高许多

#include <bits/stdc++.h>
using namespace std;
#define ll long long
#define N 0x3f3f3f3f3f3f3f3f

struct node
{
    int l;
    int r;
    ll val;
};

map <ll,int> mp;
node tree[2][12010];
ll s[3010],c[3010],pre[3010],lft[3010],rgt[3010];
int n,len;

void pushup(int id,int cur)
{
    tree[id][cur].val=min(tree[id][2*cur].val,tree[id][2*cur+1].val);
    return;
}

void build(int id,int l,int r,int cur)
{
    int m;
    tree[id][cur].l=l;
    tree[id][cur].r=r;
    tree[id][cur].val=N;
    if(l==r) return;
    m=(l+r)/2;
    build(id,l,m,2*cur);
    build(id,m+1,r,2*cur+1);
    return;
}

ll query(int id,int pl,int pr,int cur)
{
    ll res;
    if(pl<=tree[id][cur].l&&tree[id][cur].r<=pr)
    {
        return tree[id][cur].val;
    }
    res=N;
    if(pl<=tree[id][2*cur].r) res=min(res,query(id,pl,pr,2*cur));
    if(pr>=tree[id][2*cur+1].l) res=min(res,query(id,pl,pr,2*cur+1));
    return res;
}

void update(int id,int tar,ll val,int cur)
{
    if(tree[id][cur].l==tree[id][cur].r)
    {
        tree[id][cur].val=min(tree[id][cur].val,val);
        return;
    }
    if(tar<=tree[id][2*cur].r) update(id,tar,val,2*cur);
    else update(id,tar,val,2*cur+1);
    pushup(id,cur);
    return;
}

int main()
{
    ll minn;
    int i;
    scanf("%d",&n);
    for(i=1;i<=n;i++)
    {
        scanf("%lld",&s[i]);
        pre[i]=s[i];
    }
    for(i=1;i<=n;i++)
    {
        scanf("%lld",&c[i]);
    }
    sort(pre+1,pre+n+1);
    len=unique(pre+1,pre+n+1)-pre-1;
    for(i=1;i<=len;i++)
    {
        mp[pre[i]]=i;
    }
    build(0,1,len,1);
    memset(lft,0x3f,sizeof(lft));
    for(i=1;i<=n;i++)
    {
        if(mp[s[i]]-1>=1)
        {
            lft[i]=query(0,1,mp[s[i]]-1,1);
        }
        update(0,mp[s[i]],c[i],1);
    }
    build(1,1,len,1);
    memset(rgt,0x3f,sizeof(rgt));
    for(i=n;i>=1;i--)
    {
        if(mp[s[i]]+1<=len)
        {
            rgt[i]=query(1,mp[s[i]]+1,len,1);
        }
        update(1,mp[s[i]],c[i],1);
    }
    minn=N;
    for(i=1;i<=n;i++)
    {
        minn=min(minn,lft[i]+c[i]+rgt[i]);
    }
    if(minn==N) printf("-1\n");
    else printf("%lld\n",minn);
    return 0;
}

猜你喜欢

转载自blog.csdn.net/sunyutian1998/article/details/80543111