• [HDU6315]Naive Operations(线段树+树状数组)


    构造一个序列B[i]=-b[i],建一颗线段树,维护区间max,

    每次区间加后再询问该区间最大值,如果为0就在树状数组中对应的值+1(该操作可能进行多次)

    答案在树状数组中找

    其实只用一颗线段树也是可以的

    Code

    #include <cstdio>
    #include <algorithm>
    #include <cstring>
    #define mst(a) memset(a,0,sizeof(a))
    #define N 100010
    using namespace std;
    
    int n,m,b[N];
    
    inline int read(){
    	int x=0,f=1;char ch=getchar();
    	while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
    	while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();}
    	return x*f;
    }
    
    namespace BT{
    	int T[N];
    	#define lowbit(x) ((x)&(-x))
    	void add(int x,int v){for(;x<=n;x+=lowbit(x))T[x]+=v;}
    	int Q(int x){int r=0;for(;x;x-=lowbit(x))r+=T[x];return r;}
    	void ntt(){mst(T);}
    }
    
    namespace Seg{
    	#define MID int mid=(l+r)>>1,ls=id<<1,rs=id<<1|1
    	int tag[N*4];
    	struct info{
    		int x,id;
    		info(){x=id=0;}
    		info(int a,int b):x(a),id(b){}
    		friend info operator+(info a,info b){
    			return a.x>b.x?a:b;
    		}
    	}T[N*4];
    	void build(int l,int r,int id){
    		if(l==r){T[id]=info(-b[l],l);return;}
    		MID;
    		build(l,mid,ls),build(mid+1,r,rs);
    		T[id]=T[ls]+T[rs];
    	}
    	void pushdown(int l,int r,int id){
    		int &tmp=tag[id];
    		if(!tmp)return;
    		MID;
    		tag[ls]+=tmp,tag[rs]+=tmp;
    		T[ls].x+=tmp,T[rs].x+=tmp;
    		tmp=0;
    	}
    	void upd(int l,int r,int id,int L,int R,int v){
    		if(L<=l&&r<=R){tag[id]+=v;T[id].x+=v;return;}
    		pushdown(l,r,id);
    		MID;
    		if(L<=mid)upd(l,mid,ls,L,R,v);
    		if(R>=mid+1)upd(mid+1,r,rs,L,R,v);
    		T[id]=T[ls]+T[rs];
    	}
    	info Q(int l,int r,int id,int L,int R){
    		if(L<=l&&r<=R){return T[id];}
    		pushdown(l,r,id);
    		MID;
    		info res(-1e9,0);
    		if(L<=mid)res=res+Q(l,mid,ls,L,R);
    		if(R>=mid+1)res=res+Q(mid+1,r,rs,L,R);
    		return res;
    	}
    	void fft(){mst(tag),mst(T);}
    }
    void fwt(){Seg::fft(),BT::ntt();}
    int main(){
    	for(;~scanf("%d%d",&n,&m);){
    		fwt();
    		for(int i=1;i<=n;++i)b[i]=read();
    		Seg::build(1,n,1);
    		for(int i=1;i<=m;++i){
    			char s[10];scanf("%s",s);
    			int l=read(),r=read();
    			if(s[0]=='a'){
    				Seg::upd(1,n,1,l,r,1);
    				for(;;){
    					Seg::info tmp=Seg::Q(1,n,1,l,r);
    					if(tmp.x==0){
    						Seg::upd(1,n,1,tmp.id,tmp.id,-b[tmp.id]);
    						BT::add(tmp.id,1);
    					}else break;
    				}
    				
    			}else printf("%d
    ",BT::Q(r)-BT::Q(l-1));
    		}
    	}
    	return 0;
    }
    
  • 相关阅读:
    为什么用户具有Full Controls权限,但还是不能创建页面
    采用Visual Studio 2008 开发工作流模板(三)
    采用Visual Studio 2008 开发工作流模板(五)
    简单学习SPNavigationNodeCollection
    SharePoint Designer工作流的扩展
    SmartQuery_v1.0下载
    如何使用SmartQueryWebPart
    c#生成日程表并实现根据差值获得日期
    Web开发常出现的错误[个人收集]
    System.Net.Mail 发送邮件示例
  • 原文地址:https://www.cnblogs.com/void-f/p/9372092.html
Copyright © 2020-2023  润新知