1. 程式人生 > 實用技巧 >小A的題 線段樹區間賦值

小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!='\n'){
        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;
}