地中海氣候

Description

  數據範圍:\(1<=N<=10^5,1<=K<=min(2000,N),1<=a_i,p_i<=N\)ios

  

Solution

  首先比較顯然的是每次操做的時候確定是取走集合中最大的那個數,因此如今的問題就變成了動態維護最大值c++

​  然而注意到每次添加的數字只有一個,若是說這個數字加入後成爲了集合中的最大值,那麼在接下來的一輪中它一定會被取走,因此咱們考慮加入一個數\(x\)對最大值\(mx\)的影響:算法

(1)\(x>mx\),那麼\(x\)在新的一輪中會立刻被取走,不須要對\(mx\)進行修改之類的數組

(2)\(x<mx\),那麼\(mx\)在新的一輪中會被取走,咱們須要用一個比\(mx\)更小的數\(mx'\)更新這個它spa

​  注意到每次須要更新\(mx\)的時候,咱們找的必定是一個比它小的數,因此找\(mx'\)的整個過程確定是單調遞減的,因此咱們維護一個\(cnt\)數組記錄每種數字的出現次數,而後每次更新直接暴力跳到下一個非零的\(cnt\)處便可code

  這樣整個算法的複雜度就是\(O(NK)\)的啦blog

  

​  mark:轉化成比較經典的問題的時候發現複雜度仍是不對,那麼說明有一些特殊性質,不妨考慮單調ip

  

Code

#include<iostream>
#include<cstdio>
#include<cstring>
#define ll long long
using namespace std;
const int N=1e5+10;
int a[N],cnt[N];
ll sum[2];
int n,m;

int main(){
#ifndef ONLINE_JUDGE
    freopen("a.in","r",stdin);
#endif
    int x,mx,who,recmx;
    scanf("%d%d",&n,&m);
    for (int i=1;i<=n;++i) scanf("%d",a+i);
    for (int o=1;o<=m;++o){
        scanf("%d",&x);
        mx=0;
        for (int i=1;i<=x;++i){
            ++cnt[a[i]];
            mx=max(mx,a[i]);
        }
        who=0;
        sum[0]=sum[1]=0;
        recmx=0;
        for (int i=x+1;mx||recmx;++i,who^=1){
            if (recmx){
                sum[who]+=recmx; recmx=0;
            }
            else{
                sum[who]+=mx;
                --cnt[mx];
                while (cnt[mx]==0&&mx) --mx;
            }
            if (i>n) continue;
            if (a[i]>mx)
                recmx=a[i];
            else
                ++cnt[a[i]];
        }
        printf("%lld\n",sum[0]-sum[1]);
    }
}
相關文章
相關標籤/搜索