zoukankan      html  css  js  c++  java
  • Jzoj5431 序列操作

    一开始有n个非负整数h[i](1<=i<=n),接下来会进行m次操作,第i次操作给出一个数c[i],要求你选出c[i]个大于零的数并将它们减去1。

    问最多可以进行多少轮操作后无法操作(即没有c[i]个大于零的数)

    考场上脑抽认为先减小的会更优(很明显先减大的会更优啊!!!!!)

    考虑怎么维护,可以用splay

    然而正常人都用BIT因为100W两个log不会超时(其实是会的不过jz跑得快)

    先将所有数大到小排序丢入BIT中

    每次找出第c[i]个数,将所有大于ci的都减一,等于c[i]的取最后的那些,这样就能保证序列单调性

    (感觉自己好傻啊,这样下去迟早药丸)

    #pragma GCC optimize("O3")
    #pragma G++ optimize("O3")
    #include<stdio.h>
    #include<string.h>
    #include<algorithm>
    #define N 1000010
    #define LL long long
    using namespace std;
    int n,m,s[N];
    struct fenwick{
    	int w[N],S;
    	inline void add(int x,int k){ for(;x<=n;x+=x&-x) w[x]+=k; }
    	inline int sum(int x){ for(S=s[x];x;x&=x-1) S+=w[x]; return S; }
    } w;
    int lower_bound(int v){
    	int l=0,r=n;
    	for(int m;l<r;){
    		m=l+r+1>>1;
    		if(w.sum(m)<=v) r=m-1;
    		else l=m;
    	}
    	return l;
    }
    int main(){
    	freopen("sequence.in","r",stdin);
    	freopen("sequence.out","w",stdout);
    	scanf("%d%d",&n,&m);
    	for(int i=1;i<=n;++i) scanf("%d",s+i);
    	sort(s+1,s+1+n); reverse(s+1,s+1+n);
    	for(int x,v,u,i=1;i<=m;++i){
    		scanf("%d",&x);
    		v=w.sum(x);
    		if(v==0||x>n) return 0&printf("%d
    ",i-1);
    		u=lower_bound(v);
    		w.add(1,-1); w.add(u+1,1);
    		v=lower_bound(v-1);
    		w.add(v-(x-u)+1,-1); w.add(v+1,1);
    	}
    	printf("%d
    ",m);
    }

  • 相关阅读:
    php集成开发环境搭建三种方式
    阿里云服务器ftp连接后21端口无法使用的问题
    Linux CentOS7 安装FTP服务器
    WIN10分盘
    转载:常见的正则表达式
    转载:什么是分布式系统中的幂等性
    会员通过消费攒积分,升级RENEW以及降级的需求
    CASSANDRA How to import and export data
    tmp for cassandra batch delete
    SQL Insert Case When Update
  • 原文地址:https://www.cnblogs.com/Extended-Ash/p/7846030.html
Copyright © 2011-2022 走看看