zoukankan      html  css  js  c++  java
  • 【bzoj4592】[Shoi2015]脑洞治疗仪

    由于脑洞的序列不会改变,考虑用线段树维护区间内sum,左边0的个数,右边0的个数,区间内最大脑洞。对于查询l~r最大脑洞可以将l~r分成logn个区间,总复杂度O(nlogn)。

    #include<iostream>
    #include<cstdio>
    #include<cstdlib>
    #define N 800005
    using namespace std;
    int n,m,p,x,y,l,r;
    int sum[N],L[N],R[N],tg[N],v[N],Ans[N],rest,Hz,ans;
    void down(int k)
    {
    	if (tg[k]!=-1)
    	{
    		int l=k<<1,r=l|1;
    		tg[l]=tg[r]=tg[k];
    		sum[l]=v[l]*tg[k];
    		sum[r]=v[r]*tg[k];
    		if (tg[k]==0) L[l]=R[l]=Ans[l]=v[l],L[r]=R[r]=Ans[r]=v[r];
    		else L[l]=R[l]=L[r]=Ans[l]=R[r]=Ans[r]=0;
    		tg[k]=-1;
    	}
    }
    void up(int k)
    {
    	int l=k<<1,r=l|1;sum[k]=sum[l]+sum[r];
    	if (!sum[l]) L[k]=L[l]+L[r];else L[k]=L[l];
    	if (!sum[r]) R[k]=R[l]+R[r];else R[k]=R[r];
    	Ans[k]=max(max(Ans[l],Ans[r]),R[l]+L[r]);
    }
    void build(int k,int l,int r)
    {
    	if (l==r){v[k]=1;return;}
    	int mid=(l+r)>>1;
    	build(k<<1,l,mid);
    	build(k<<1|1,mid+1,r);
    	v[k]=v[k<<1]+v[k<<1|1];
    }
    void add(int k,int l,int r,int x,int y)
    {
    	if (x<=l&&r<=y)
    	{
    		sum[k]=0;tg[k]=0;
    		L[k]=R[k]=v[k];
    		return;
    	}
    	int mid=(l+r)>>1;
    	down(k);
    	if (x<=mid) add(k<<1,l,mid,x,y);
    	if (y>mid) add(k<<1|1,mid+1,r,x,y);
    	up(k);
    }
    int Get(int k,int l,int r,int x,int y)
    {
    	if (x<=l&&r<=y) return sum[k];
    	int mid=(l+r)>>1;
    	down(k);
    	int Ans=0;
    	if (x<=mid) Ans+=Get(k<<1,l,mid,x,y);
    	if (y>mid) Ans+=Get(k<<1|1,mid+1,r,x,y);
    	return Ans;
    }
    void fix(int k,int l,int r,int x,int y)
    {
    	if (!rest) return;
    	if (x<=l&&r<=y&&rest>=v[k]-sum[k])
    	{
    		rest-=v[k]-sum[k];
    		tg[k]=1;Ans[k]=0;
    		L[k]=R[k]=0;sum[k]=v[k];
    		return;
    	}
    	down(k);
    	int mid=(l+r)>>1;
    	if (x<=mid) fix(k<<1,l,mid,x,y);
    	if (y>mid) fix(k<<1|1,mid+1,r,x,y);
    	up(k);
    }
    void qry(int k,int l,int r,int x,int y)
    {
    	if (x<=l&&r<=y)
    	{
    		ans=max(ans,Ans[k]);
    		ans=max(ans,Hz+L[k]);
    		if (R[k]==v[k]) Hz+=R[k];else Hz=R[k];
    		return;
    	}
    	down(k);
    	int mid=(l+r)>>1;
    	if (x<=mid) qry(k<<1,l,mid,x,y);
    	if (y>mid) qry(k<<1|1,mid+1,r,x,y);
    }
    int main()
    {
    	scanf("%d%d",&n,&m);
    	build(1,1,n);
    	sum[1]=v[1];tg[1]=1;
    	for (int i=1;i<=m;i++)
    	{
    		scanf("%d%d%d",&p,&l,&r);
    		if (p==0) add(1,1,n,l,r);
    		else if (p==1)
    		{
    			scanf("%d%d",&x,&y);
    			rest=Get(1,1,n,l,r);
    			add(1,1,n,l,r);
    			fix(1,1,n,x,y);
    		}
    		else
    		{
    			ans=0;Hz=0;qry(1,1,n,l,r);
    			printf("%d
    ",ans);
    		}
    	}
    	return 0;
    }
    

      

  • 相关阅读:
    基于Maven的MyBatis Generator逆向工程
    JQuery对象调用reset方法:Uncaught TypeError: $(...).reset is not a function
    死锁编码及定位分析
    线程池的简介及底层原理
    转载:Mysql8.0忘记 root 密码, 如何修改?
    synchronized 和 Lock 有什么区别?
    java 中的阻塞队列及生产者-消费者中的简单应用
    java 中 CountDownLatch、CyclicBarrier 和 Semaphore 的简单使用
    java中的公平锁、非公平锁、可重入锁、递归锁、自旋锁、独占锁和共享锁
    Java 集合类的线程安全问题及解决方法
  • 原文地址:https://www.cnblogs.com/yangjiyuan/p/5519945.html
Copyright © 2011-2022 走看看