• [SCOI2010]序列操作


    操作0、1:区间赋值

    操作2:区间异或

    操作3:区间求和

    操作4:区间最长连续段

    我们用线段树打lazy标记的方式维护:某段区间从左向右和从右向左延伸的0和1的长度、某段区间内0和1的最长长度、区间和。

    然后分类讨论pushdown与pushup即可

    #include"cstdio"
    #include"cstring"
    #include"iostream"
    #include"algorithm"
    using namespace std;
    
    const int MAXN=1<<17;
    
    int n,m;
    int a[MAXN];
    int lef[2][MAXN<<1],rig[2][MAXN<<1],mx[2][MAXN<<1];
    int sm[MAXN<<1],tag[MAXN<<1],chg[MAXN<<1];
    
    inline int read()
    {
    	int x=0;char ch=getchar();
    	while(ch<'0'||'9'<ch) ch=getchar();
    	while('0'<=ch&&ch<='9') x=(x<<3)+(x<<1)+(ch^48),ch=getchar();
    	return x;
    }
    
    inline void pushup(int k,int l,int r)
    {
    	if(l==r) return;
    	int i=k<<1,mid=l+r>>1;
    	lef[0][k]=lef[0][i]==mid-l+1?lef[0][i]+lef[0][i|1]:lef[0][i];
    	lef[1][k]=lef[1][i]==mid-l+1?lef[1][i]+lef[1][i|1]:lef[1][i];
    	rig[0][k]=rig[0][i|1]==r-mid?rig[0][i|1]+rig[0][i]:rig[0][i|1];
    	rig[1][k]=rig[1][i|1]==r-mid?rig[1][i|1]+rig[1][i]:rig[1][i|1];
    	mx[0][k]=max(rig[0][i]+lef[0][i|1],max(mx[0][i],mx[0][i|1]));
    	mx[1][k]=max(rig[1][i]+lef[1][i|1],max(mx[1][i],mx[1][i|1]));
    	sm[k]=sm[i]+sm[i|1];
    	return;
    }
    
    void build(int k,int l,int r)
    {
    	chg[k]=-1;
    	if(l==r){
    		if(a[l]) sm[k]=1;
    		lef[a[l]][k]=rig[a[l]][k]=mx[a[l]][k]=1;
    		return;
    	}int i=k<<1,mid=l+r>>1;
    	build(i,l,mid);build(i|1,mid+1,r);
    	pushup(k,l,r);
    	return;
    }
    
    void pushdown(int k,int l,int r)
    {
    	if(l==r||(!tag[k]&&chg[k]==-1)) return;
    	int i=k<<1,mid=l+r>>1;
    	if(tag[k]){
    		if(chg[i]!=-1) chg[i]^=1;
    		if(chg[i|1]!=-1) chg[i|1]^=1;
    		tag[i]^=1;tag[i|1]^=1;
    		sm[i]=mid-l+1-sm[i];sm[i|1]=r-mid-sm[i|1];
    		swap(lef[0][i],lef[1][i]),swap(rig[0][i],rig[1][i]),swap(mx[0][i],mx[1][i]);
    		swap(lef[0][i|1],lef[1][i|1]),swap(rig[0][i|1],rig[1][i|1]),swap(mx[0][i|1],mx[1][i|1]);
    		tag[k]=0;
    	}if(chg[k]!=-1){
    		tag[i]=tag[i|1]=0;chg[i]=chg[i|1]=chg[k];
    		sm[i]=chg[k]?mid-l+1:0;sm[i|1]=chg[k]?r-mid:0;
    		lef[chg[k]][i]=rig[chg[k]][i]=mx[chg[k]][i]=mid-l+1;
    		lef[chg[k]^1][i]=rig[chg[k]^1][i]=mx[chg[k]^1][i]=0;
    		lef[chg[k]][i|1]=rig[chg[k]][i|1]=mx[chg[k]][i|1]=r-mid;
    		lef[chg[k]^1][i|1]=rig[chg[k]^1][i|1]=mx[chg[k]^1][i|1]=0;
    		chg[k]=-1;
    	}return;
    }
    
    void cchg(int k,int l,int r,int le,int ri,int v)
    {
    	pushdown(k,l,r);
    	if(le<=l&&r<=ri){
    		sm[k]=v?r-l+1:0;
    		lef[v][k]=rig[v][k]=mx[v][k]=r-l+1;
    		lef[v^1][k]=rig[v^1][k]=mx[v^1][k]=0;
    		chg[k]=v;
    		return;
    	}int i=k<<1,mid=l+r>>1;
    	if(le<=mid) cchg(i,l,mid,le,ri,v);
    	if(mid<ri) cchg(i|1,mid+1,r,le,ri,v);
    	pushup(k,l,r);
    	return;
    }
    
    void ctag(int k,int l,int r,int le,int ri)
    {
    	pushdown(k,l,r);
    	if(le<=l&&r<=ri){
    		tag[k]=1;
    		sm[k]=r-l+1-sm[k];
    		swap(lef[0][k],lef[1][k]);
    		swap(rig[0][k],rig[1][k]);
    		swap(mx[0][k],mx[1][k]);
    		return;
    	}int i=k<<1,mid=l+r>>1;
    	if(le<=mid) ctag(i,l,mid,le,ri);
    	if(mid<ri) ctag(i|1,mid+1,r,le,ri);
    	pushup(k,l,r);
    	return;
    }
    
    int cask1(int k,int l,int r,int le,int ri)
    {
    	pushdown(k,l,r);pushup(k,l,r);
    	if(le<=l&&r<=ri) return sm[k];
    	int i=k<<1,mid=l+r>>1,sum=0;
    	if(le<=mid) sum+=cask1(i,l,mid,le,ri);
    	if(mid<ri) sum+=cask1(i|1,mid+1,r,le,ri);
    	return sum;
    }
    
    int cask2(int k,int l,int r,int le,int ri)
    {
    	pushdown(k,l,r);pushup(k,l,r);
    	if(le<=l&&r<=ri) return mx[1][k];
    	int i=k<<1,mid=l+r>>1,mxx=0;
    	if(le<=mid&&mid<ri) mxx=max(max(cask2(i,l,mid,le,ri),cask2(i|1,mid+1,r,le,ri)),min(mid-le+1,rig[1][i])+min(ri-mid,lef[1][i|1]));
    	else if(le<=mid) mxx=cask2(i,l,mid,le,ri);
    	else if(mid<ri) mxx=cask2(i|1,mid+1,r,le,ri);
    	return mxx;
    }
    
    int main()
    {
    	scanf("%d%d",&n,&m);
    	for(int i=1;i<=n;++i) a[i]=read();
    	build(1,1,n);
    	while(m--){
    		int p=read(),l=read()+1,r=read()+1;
    		if(p==0) cchg(1,1,n,l,r,0);
    		else if(p==1) cchg(1,1,n,l,r,1);
    		else if(p==2) ctag(1,1,n,l,r);
    		else if(p==3) printf("%d
    ",cask1(1,1,n,l,r));
    		else printf("%d
    ",cask2(1,1,n,l,r));
    	}return 0;
    }
    
  • 相关阅读:
    模拟器登陆
    mab算法
    用户投票排名算法总结
    vue中路由
    利用ajax全局设置实现拦截器
    对于 前端请求Django 后端服务出现403 Forbidden (CSRF token missing or incorrect.) 问题的解析
    Datatable 插入一行数据到第一行
    Datatable 导出到execl 官网demo
    jquery cookie操作
    on绑定事件支持的事件类型
  • 原文地址:https://www.cnblogs.com/AH2002/p/10206071.html
Copyright © 2020-2023  润新知