zoukankan      html  css  js  c++  java
  • 【BZOJ1901】【 ZOJ2112】- Dynamic Rankings(整体二分)

    传送门

    其实和前面那道K-th Number几乎一模一样吧

    只需要在中途添加修改操作就可以了

    注意由于整体二分的特殊性

    修改操作要先将原来的贡献给排除掉在添加这一次操作的贡献

    还有数组大小

    具体看代码就可以了

    #include<algorithm>
    #include<iostream>
    #include<cstdio>
    #include<cstring>
    using namespace std;
    const int N=400005;
    inline int read(){
    	char ch=getchar();
    	int res=0,f=1;
    	while(!isdigit(ch)){if(ch=='-')f=-1;ch=getchar();}
    	while(isdigit(ch))res=(res<<3)+(res<<1)+(ch^48),ch=getchar();
    	return res*f;
    }
    struct ask{
    	int l,r,k,pos,op;
    }q[N],q1[N],q2[N];
    int tr[N],ans[N],a[N],n,m,cnt,tot;
    char c[5];
    inline int lowbit(int x){
    	return (x&-x);
    }
    inline void add(int pos,int k){
    	for(;pos<=n;pos+=lowbit(pos))tr[pos]+=k;
    }
    inline int query(int pos,int res=0){
    	for(;pos;pos-=lowbit(pos))res+=tr[pos];return res;
    }
    void solve(int l,int r,int st,int des){
    	if(l>r||st>des)return;
    	if(l==r){
    		for(int i=st;i<=des;i++)if(q[i].op)ans[q[i].pos]=l;
    		return;
    	}
    	int mid=(l+r)>>1,cnt1=0,cnt2=0;
    	for(int i=st;i<=des;i++){
    		if(q[i].op){
    			int tmp=query(q[i].r)-query(q[i].l-1);
    			if(tmp>=q[i].k)q1[++cnt1]=q[i];
    			else q[i].k-=tmp,q2[++cnt2]=q[i];
    		}
    		else{
    			if(q[i].l<=mid){
    				q1[++cnt1]=q[i],add(q[i].pos,q[i].r);
    			}
    			else q2[++cnt2]=q[i]; 
    		}
    	}
        for(int i=1;i<=cnt1;i++) if(!q1[i].op) add(q1[i].pos, -q1[i].r);
        for(int i=1;i<=cnt1;i++) q[st+i-1]=q1[i];
        for(int i=1;i<=cnt2;i++) q[st+cnt1+i-1]=q2[i];
        solve(l, mid, st, st+cnt1-1); solve(mid+1, r, st+cnt1, des);
    }
    int main(){
    	int T=read();
    	while(T--){
    		cnt=tot=0,memset(tr,0,sizeof(tr));
    		n=read(),m=read();
    		for(int i=1;i<=n;++i){
    			a[i]=read();q[++cnt]=(ask){a[i],1,0,i,0};
    		}
    		for(int i=1;i<=m;i++){
    			scanf("%s",c+1);
    			if(c[1]=='Q'){
    				int l=read(),r=read(),k=read();q[++cnt]=(ask){l,r,k,++tot,1};
    			}
    			else{
    				int pos=read(),k=read();
    				q[++cnt]=(ask){a[pos],-1,0,pos,0},q[++cnt]=(ask){a[pos]=k,1,0,pos,0};
    			}
    		}
    		solve(-1e9,1e9,1,cnt);
    		for(int i=1;i<=tot;i++)cout<<ans[i]<<'
    ';
    	}
    }
    
    
  • 相关阅读:
    hdu 5115 区间dp ***
    CF 149D Coloring Brackets 区间dp ****
    区间dp总结
    hdu 5284 BestCoder Round #48 ($) 1001 水题 *
    vijos 1038 括号+路径 ***
    vijos 1037 ***
    vijos 1028 LIS *
    使用alpine 构建 golang 运行容器
    Go Http包解析:为什么需要response.Body.Close()
    如果open的file不close , 会有什么样的影响
  • 原文地址:https://www.cnblogs.com/stargazer-cyk/p/10366361.html
Copyright © 2011-2022 走看看