zoukankan      html  css  js  c++  java
  • BZOJ 4631: 踩气球

    对于每个点开一棵权值线段树,以区间的左端点为值插入右端点的权值线段树中,并查集维护i左边第一个不被删空的位置,为F[i]

    当一个点被删空的时候,这棵线段树中>F[i]的位置即为答案,清空以后把i和F[i]这两棵线段树合并

    #include<cstdio>
    using namespace std;
    int cnt,Lastans,F[1000005],a[1000005],ls[2000005],rs[2000005],sz[2000005],root[100005];
    int find(int x){
    	if (!a[F[x]]) F[x]=find(F[x]);
    	return F[x];
    }
    void update(int t){
    	sz[t]=sz[ls[t]]+sz[rs[t]];
    }
    void del(int t,int l,int r,int x,int y){
    	if (!t) return;
    	if (r<x || l>y) return;
    	if (l>=x && r<=y){
    		Lastans+=sz[t];
    		sz[t]=0;
    		return;
    	}
    	int mid=(l+r)>>1;
    	del(ls[t],l,mid,x,y);
    	del(rs[t],mid+1,r,x,y);
    	update(t);
    }
    void insert(int &t,int l,int r,int x){
    	if (!t) t=++cnt;
    	sz[t]++;
    	if (l==r) return;
    	int mid=(l+r)>>1;
    	if (x<=mid) insert(ls[t],l,mid,x);
    	else insert(rs[t],mid+1,r,x);
    }
    int merge(int x,int y){
    	if (!x || !y) return x^y;
    	sz[x]+=sz[y];
    	ls[x]=merge(ls[x],ls[y]);
    	rs[x]=merge(rs[x],rs[y]);
    	return x;
    }
    int main(){
    	int n,m;
    	scanf("%d%d",&n,&m);
    	for (int i=1; i<=n; i++) scanf("%d",&a[i]);
    	for (int i=1; i<=n; i++) F[i]=i-1;
    	for (int i=1; i<=m; i++){
    		int l,r;
    		scanf("%d%d",&l,&r);
    		insert(root[r],1,n,l);
    	}
    	a[0]=1;
    	int q;
    	scanf("%d",&q);
    	while (q--){
    		int x;
    		scanf("%d",&x);
    		x=(x+Lastans-1)%n+1;
    		a[x]--;
    		if (!a[x]){
    			int fx=find(x);
    			del(root[x],1,n,fx+1,n);
    			root[fx]=merge(root[fx],root[x]);
    		}
    		printf("%d
    ",Lastans);
    	}
    	return 0;
    }
    

      

  • 相关阅读:
    转:高并发场景下强一致预算/库存扣减方案
    转:Dubbo性能调优参数及原理
    转:java线程状态说明,Jstack线程状态BLOCKED/TIMED_WAITING/WAITING解释
    使用增强学习法之SQ3R主动阅读
    建立实用投资计划
    使用smarty方法实现目标
    主动学习
    小知识
    大脑的处理模式
    真正的随笔
  • 原文地址:https://www.cnblogs.com/silenty/p/9838515.html
Copyright © 2011-2022 走看看