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);
    }

  • 相关阅读:
    PATA 1071 Speech Patterns.
    PATA 1027 Colors In Mars
    PATB 1038. 统计同成绩学生(20)
    1036. 跟奥巴马一起编程(15)
    PATA 1036. Boys vs Girls (25)
    PATA 1006. Sign In and Sign Out (25)
    读取web工程目录之外的图片并显示
    DOS命令
    java连接oracle集群
    servlet
  • 原文地址:https://www.cnblogs.com/Extended-Ash/p/7846030.html
Copyright © 2011-2022 走看看