小A的题 线段树区间赋值

小A的题

描述

由于小 A 实在是太菜了,因此他现在需要你的帮助: 现在小 A 手上有一个凌乱的 01 串,他想通过若干次对于这个 01 串的局部排序将它变成一个有趣的 01 序列。 现在有两种操作:

输入格式

l r 00 表示把区间 [l,r][给升序排序

l r 11 表示把区间 [l,r]给降序排序

然后小 A 这个菜鸡想知道在 m次操作之后序列长啥样。

输出格式

第一行一个 01 串 S。 第二行一个整数 m。 接下来 m 行每行三个整数 l,r,x,保证(l le r and x=0) 中的一个。

m 次操作之后的 01 串

数据范围
(|S| le 1000000,m le 500000∣S∣≤1000000,m≤500000)

输出时每行末尾的多余空格,不影响答案正确性

样例输入
11001
1
2 4 0
样例输出
10011

因为区间只有01,降序排序之后左边全是1,右边全是0,所以,维护区间1的个数,0的个数=区间长度-1的个数。

#include<bits/stdc++.h>
using namespace std;
const int inf=0x3f3f3f3f,mod=1e9+7,MAXN=1e6+4;
#define lson (i<<1)
#define rson (i<<1|1)
#define mid ((l+r)>>1)
int one[MAXN<<2],n,t;//one:1的个数
bool lazy[MAXN<<2];
char ans[MAXN];
void down(int i,int l,int r){
    one[lson]=one[i]?(mid-l+1):0;
    one[rson]=one[i]?r-mid:0;
    lazy[lson]=lazy[rson]=1;
    lazy[i]=0;
}
int sum(int x,int y,int i=1,int l=1,int r=n){
    if(x<=l&&r<=y)return one[i];
    int res=0;
    if(lazy[i])down(i,l,r);
    if(x<=mid)res+=sum(x,y,lson,l,mid);
    if(y>mid)res+=sum(x,y,rson,mid+1,r);
    return res;
}
void up(int i,int l,int r){
    one[i]=one[lson]+one[rson];
}
void change(int x,int y,int val,int i=1,int l=1,int r=n){
    if(x>y)return;
    if(x<=l&&r<=y){
        lazy[i]=1;
        one[i]=val?r-l+1:0;
        return;
    }
    if(lazy[i])down(i,l,r);
    if(x<=mid)change(x,y,val,lson,l,mid);
    if(y>mid)change(x,y,val,rson,mid+1,r);
    up(i,l,r);
}
void build(int i=1,int l=1,int r=n){
    if(l==r){
        if(ans[l]=='1')one[i]=1;
        return;
    }
    build(lson,l,mid);
    build(rson,mid+1,r);
    up(i,l,r);
}
void print(int i=1,int l=1,int r=n){
        if(l==r){
        putchar(one[i]+48);
        return;
    }
if(lazy[i])down(i,l,r);
   print(lson,l,mid);
    print(rson,mid+1,r);
}
int main() {
    char ch=getchar();
    while(ch!='
'){
        ans[++n]=ch;
        ch=getchar();
    }
    build();
    scanf("%d",&t);
    int x,y,op,yi,m;
    while(t--){
        scanf("%d%d%d",&x,&y,&op);
        if(x>y)continue;
        yi=sum(x,y);
        if(!yi||y-x+1==yi)continue;
        if(op==1){
            m=yi+x-1;
            change(x,m,1);
            change(m+1,y,0);
        }else if(op==0){
            m=y-yi;
            change(x,m,0);
            change(m+1,y,1);
        }
    }
	print();
    return 0;
}
原文地址:https://www.cnblogs.com/foursmonth/p/14145251.html