[Codeforces Round#312 Div.2] A Simple Task 【线段树+lazy_tag】

来源:互联网 发布:gfriend整容知乎 编辑:程序博客网 时间:2024/06/05 15:52

[Codeforces Round#312 Div.2] A Simple Task

题目描述

给出一个长度为n的字符串,给出q个区间,要求依次将区间内的字符按非升/非降进行排序,输出最后的字符串。

数据范围

1n105,0q50000

样例输入

10 5
abacdabcda
7 10 0
5 8 1
1 4 0
3 6 0
7 10 1

样例输出

cbcaaaabdd

其实一开始我是不愿意写26个线段树的。。。

我固执地使用自己的单个线段树版,每次区间都需要从1循环到26当前区间的cnt[i]这个直接导致了我做此题用了半天!!8个小时!!从test9 TLE 升级到test22 TLE 最后升级到test53 TLE再也切不动了。。。

正题:

用26个线段树维护每个区间该字符的个数,(从小到大/从大到小)更替这个区间的字符串,所以就不用sort排序了,需要用lazy懒标记,2000+ms过。【该用空间的地方就用0 0】
对了,还有一个不起眼的小优化,也不知道它为我最后的AC贡献了多少时间。。。就是如果操作中出现两个区间前者被后者框在了里面,就可以删去前者,我用了手写栈。。。

码:

#include<iostream>#include<cstring>#include<cstdio>#include<string>#define LCH(i) (2 * i)#define RCH(i) (2 * i + 1)const int maxn = 1e5;const int maxl = 26;const int maxo = 50000;using namespace std;struct OP{    int l, r, ope;}op[maxo + 5], sta[maxo + 5];struct T{    int lc, rc, cnt;    int size(){        if(lazy == 1)return rc - lc + 1;        else return 0;    }    int lazy;}tree[maxl + 5][maxn * 4];int n, q, top, tmp[maxl + 5];char str[maxn + 5];void del(){    for(int i = 1; i <= q; i ++){        while(top > 0 && sta[top].l >= op[i].l && sta[top].r <= op[i].r) -- top;        sta[++ top] = op[i];    }    for(int i = 1; i <= top; i ++)        op[i] = sta[i];    q = top;}void built(int i, int l, int r, int alpha){    tree[alpha][i].lc = l, tree[alpha][i].rc = r;    if(l == r){        if(str[l] - 'a' == alpha)tree[alpha][i].cnt ++;        return ;    }    int mid = (l + r) / 2;    built(LCH(i), l, mid, alpha);    built(RCH(i), mid + 1, r, alpha);    tree[alpha][i].cnt = tree[alpha][LCH(i)].cnt + tree[alpha][RCH(i)].cnt;    return;}void query(int i, int l, int r, int alpha){    if(tree[alpha][i].rc < l || tree[alpha][i].lc > r)return ;    if(tree[alpha][i].lc >= l && tree[alpha][i].rc <= r){        tmp[alpha] += tree[alpha][i].cnt;        tree[alpha][i].lazy = 1;        return;    }    else {        if(tree[alpha][i].lazy){            tree[alpha][LCH(i)].lazy = tree[alpha][i].lazy;            tree[alpha][RCH(i)].lazy = tree[alpha][i].lazy;            tree[alpha][LCH(i)].cnt = tree[alpha][LCH(i)].size();            tree[alpha][RCH(i)].cnt = tree[alpha][RCH(i)].size();            tree[alpha][i].lazy = 0;        }        query(LCH(i), l, r, alpha);        query(RCH(i), l, r, alpha);    }}void update(int i, int l, int r, int alpha, int val){    if(tree[alpha][i].lc > r || tree[alpha][i].rc < l)return;    if(tree[alpha][i].lc >= l && tree[alpha][i].rc <= r){        tree[alpha][i].lazy = val;        tree[alpha][i].cnt = tree[alpha][i].size();        return;    }    else {        if(tree[alpha][i].lazy){            tree[alpha][LCH(i)].lazy = tree[alpha][i].lazy;            tree[alpha][RCH(i)].lazy = tree[alpha][i].lazy;            tree[alpha][LCH(i)].cnt = tree[alpha][LCH(i)].size();            tree[alpha][RCH(i)].cnt = tree[alpha][RCH(i)].size();            tree[alpha][i].lazy = 0;        }        update(LCH(i), l, r, alpha, val);        update(RCH(i), l, r, alpha, val);        tree[alpha][i].cnt = tree[alpha][LCH(i)].cnt + tree[alpha][RCH(i)].cnt;        return;    }}int main(){    scanf("%d %d\n", &n, &q);    gets(str + 1);    for(int i = 1; i <= q; i ++)        scanf("%d%d%d", &op[i].l, &op[i].r, &op[i].ope);    del();//小优化    for(int i = 0; i < maxl; i ++)        built(1, 1, n, i);    int xlen;    for(int i = 1; i <= q; i ++){        for(int j = 0; j < maxl; j ++){            query(1, op[i].l, op[i].r, j);            update(1, op[i].l, op[i].r, j, 2);        }        xlen = op[i].l;        if(op[i].ope){            for(int j = 0; j < maxl; j ++){                if(!tmp[j])continue;                update(1, xlen, xlen + tmp[j] - 1, j, 1);                while(tmp[j]){//更新当前字符串                    str[xlen ++] = j + 'a';                    tmp[j] --;                }            }        }        else{            for(int j = maxl - 1; j >= 0; j --){                if(!tmp[j])continue;                update(1, xlen, xlen + tmp[j] - 1, j, 1);                while(tmp[j]){//更新当前字符串                    str[xlen ++] = j + 'a';                    tmp[j] --;                }            }        }        //printf("%s", str + 1);        //puts("");    }    printf("%s", str + 1);}
0 0
原创粉丝点击