HDU6047 Maximum Sequence

題目連接

題意

​ 給定長度爲n的數列A和數列B,利用已經存在的兩數列A,B生成A數列的後續an+1,an+2,......,a2n 項,要求生成的新的項時滿足條件aimax{ajjbkj<i} ,式中k爲所選用的數,每個bk 限定只能選一次。求取max{2nn+1ai}

分析

​ 要求取最大值,顯然ai=max{ajjbkj<i} ,問題轉換成了如何分配k使得最後和最大。假定appaqq 對於所有的p<q 成立,attaqq 對於所有的t>q 成立。那麼對於所有的bkq 顯然生成的數均爲aqq ,考慮到所有生成的數ai 對後續的影響爲aii ,想要使得後續的數儘可能的大,由於ai 固定不變,則在i 最小時aii 最大。所以可以貪心的採用每次生成的數均爲可行方案中最大的結果,最後求取2nn+1ai 的結果必然也是最大值。比賽期間使用的優先隊列來快速尋找到最大的數,然後用樹狀數組記錄bk 的值,快速能夠生成的ai 的具體數列。賽後發現其實想多了,不需要使用樹狀數組,一個前綴和就可以獲取具體數量了。具體可以看看比賽時的代碼

代碼

#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<vector>
#include<map>
#include<cmath>
#include<queue>
using namespace std;
#define LL long long
#define MAXN 250250
const int mod=1e9+7;
struct Node{
    int v,idx;
    Node(int _v,int _idx):v(_v),idx(_idx){}
    Node(){}
    friend bool operator<(Node n1,Node n2){
        if(n1.v!=n2.v)
            return n1.v<n2.v;
        return n1.idx<n2.idx;
    }
};
int bin[MAXN];
int a[MAXN];
int b[MAXN];
int lowbit(int x){
    return x&-x;
}
int sum(int x){
    int ret=0;
    while(x){
        ret+=bin[x];
        x-=lowbit(x);
    }
    return ret;
}
int add(int x){
    while(x<MAXN){
        bin[x]++;
        x+=lowbit(x);
    }
}

int query(int x,int y){
    return sum(y)-sum(x-1);
}
int main(){
    int n;
    while(~scanf("%d",&n)){
        priority_queue<Node> q;
        memset(bin,0,sizeof(bin));
        for(int i=1;i<=n;++i){
            scanf("%d",&a[i]);
            q.push(Node(a[i]-i,i));
        }
        for(int i=1;i<=n;++i){
            scanf("%d",&b[i]);
            add(b[i]);
        }
        LL ans=0;
        int res=n,mx=0,pos=n+1;
        while(res && !q.empty()){
            Node tmp=q.top();
            q.pop();
            if(tmp.idx<=mx)
                continue;
            if(tmp.idx>mx){
                if(tmp.idx>n){
                    ans+=tmp.v*1ll*res;
                    res=0;
                    continue;
                }
                else{
                    int num=query(mx+1,tmp.idx);
                    ans+=tmp.v*1ll*num;
                    q.push(Node(tmp.v-pos,pos));
                    pos+=num;
                    res-=num;
                    mx=tmp.idx;
                    continue;
                }
            }
        }
        ans%=mod;
        printf("%I64d\n",ans);
    }
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章