zoukankan      html  css  js  c++  java
  • 地中海气候

    ### Description

      数据范围:(1<=N<=10^5,1<=K<=min(2000,N),1<=a_i,p_i<=N)

      

    Solution

      首先比较显然的是每次操作的时候肯定是取走集合中最大的那个数,所以现在的问题就变成了动态维护最大值

    ​  然而注意到每次添加的数字只有一个,如果说这个数字加入后成为了集合中的最大值,那么在接下来的一轮中它必定会被取走,所以我们考虑加入一个数(x)对最大值(mx)的影响:

    (1)(x>mx),那么(x)在新的一轮中会马上被取走,不需要对(mx)进行修改之类的

    (2)(x<mx),那么(mx)在新的一轮中会被取走,我们需要用一个比(mx)更小的数(mx')更新这个它

    ​  注意到每次需要更新(mx)的时候,我们找的一定是一个比它小的数,所以找(mx')的整个过程肯定是单调递减的,所以我们维护一个(cnt)数组记录每种数字的出现次数,然后每次更新直接暴力跳到下一个非零的(cnt)处即可

      这样整个算法的复杂度就是(O(NK))的啦

      

    ​  mark:转化成比较经典的问题的时候发现复杂度还是不对,那么说明有一些特殊性质,不妨考虑单调

      

    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
    ",sum[0]-sum[1]);
    	}
    }
    
  • 相关阅读:
    2016.11.9 小测试
    【noip】跟着洛谷刷noip题2
    【长沙集训】2017.10.10
    【noip】跟着洛谷刷noip题
    Oracle-函数-translate
    bit,byte,char,string区别与基本类型认识
    通俗地讲,Netty 能做什么?
    oracle判断一个字符串中是否包含另外一个字符串
    Oracle导入导出数据库(exp/imp和expdp/impdp的区别)
    同步异步以及阻塞和非阻塞的区别
  • 原文地址:https://www.cnblogs.com/yoyoball/p/10145831.html
Copyright © 2011-2022 走看看