• 【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;
    }
    

      

  • 相关阅读:
    (转载)安装Android时Could not find D:\Android\a...sdkwindows\tools\adb.exe
    (转载)Exception in thread "main" java.lang.NoClassDefFoundError错误信息
    (转载)java函数参数类型后添加三点的用法
    (转载)一个fork的面试题
    javascript event事件再次封装了,兼容大多数浏览器
    SINA多功能弹窗已经摘出来
    Observer Design Pattern Using JavaScript
    CSS Hacks for IE,IE 也可以很完美
    N久前写的一个JSONP请求方法
    JS模拟滚动条雏形(待进一步规整)
  • 原文地址:https://www.cnblogs.com/yangjiyuan/p/5519945.html
Copyright © 2020-2023  润新知