CF558E A Simple Task

Posted qihoo360

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了CF558E A Simple Task相关的知识,希望对你有一定的参考价值。

题目链接
用权值线段树维护每个字母在([l,r])出现的次数,每次修改把每个字母在区间的出现次数记下来,然后清空这段区间,再按顺序插进去就好了。
时间复杂度(O(nlog n*26))
(好久没写正常的维护和的线段树了,这次还要打清零的标记,能一遍写过,好开森)

#include <cstdio>
#include <cstring>
int o; char ch;
inline int read(){
    o = 0; ch = getchar();
    while(ch < '0' || ch > '9') ch = getchar();
    while(ch >= '0' && ch <= '9'){ o = o * 10 + ch - '0'; ch = getchar(); }
    return o;
}
const int MAXN = 100010;
struct SegTree{
    #define left (now << 1)
    #define right (now << 1 | 1)
    int sum[MAXN << 2], s[MAXN << 2], c[MAXN << 2];
    inline void pushup(int now){
        sum[now] = sum[left] + sum[right];
    }
    inline void pushdown(int now, int k){
        if(c[now]){
          sum[left] = sum[right] = s[left] = s[right] = 0;
          c[left] = c[right] = 1;
          c[now] = 0;
        }
        if(s[now]){
          int len = k >> 1;
          sum[left] += (k - len) * s[now];
          sum[right] += len * s[now];
          s[left] = s[right] = s[now];
          s[now] = 0;
        }
    }
    void update(int now, int l, int r, int wl, int wr){
        if(l > wr || r < wl) return;
        if(l >= wl && r <= wr){ sum[now] += (r - l + 1); ++s[now]; return; }
        pushdown(now, r - l + 1);
        int mid = (l + r) >> 1;
        update(left, l, mid, wl, wr);
        update(right, mid + 1, r, wl, wr);
        pushup(now);
    }
    void clear(int now, int l, int r, int wl, int wr){
        if(l > wr || r < wl) return;
        if(l >= wl && r <= wr){ sum[now] = 0; s[now] = 0; c[now] = 1; return; }
        pushdown(now, r - l + 1);
        int mid = (l + r) >> 1;
        clear(left, l, mid, wl, wr);
        clear(right, mid + 1, r, wl, wr);
        pushup(now);
    }
    int query(int now, int l, int r, int wl, int wr){
        if(l > wr || r < wl) return 0;
        if(l >= wl && r <= wr) return sum[now];
        pushdown(now, r - l + 1);
        int mid = (l + r) >> 1, ans = 0;
        ans += query(left, l, mid, wl, wr);
        ans += query(right, mid + 1, r, wl, wr);
        return ans;
    }
}s[27];
int n, m, A, B, C, tmp[27];
char a[MAXN];
int main(){
    n = read(); m = read();
    scanf("%s", a);
    int len = strlen(a);
    for(int i = 0; i < len; ++i)
       s[a[i] - 'a'].update(1, 1, n, i + 1, i + 1);
    for(int i = 1; i <= m; ++i){
       A = read(); B = read(); C = read();
       if(C){
         for(int j = 0; j < 26; ++j)
            tmp[j] = s[j].query(1, 1, n, A, B), s[j].clear(1, 1, n, A, B);
         int cur = A;
         for(int j = 0; j < 26; ++j)
            if(tmp[j])
              s[j].update(1, 1, n, cur, (cur + tmp[j]) - 1), cur += tmp[j];
       }
       else{
         for(int j = 0; j < 26; ++j)
            tmp[j] = s[j].query(1, 1, n, A, B), s[j].clear(1, 1, n, A, B);
         int cur = B;
         for(int j = 0; j < 26; ++j)
            if(tmp[j])
              s[j].update(1, 1, n, (cur - tmp[j]) + 1, cur), cur -= tmp[j];
       }
    }
    for(int i = 1; i <= n; ++i)
       for(int j = 0; j < 26; ++j)
          if(s[j].query(1, 1, n, i, i)){
            printf("%c", j + 'a');
            break;
          }
    return 0;
}

以上是关于CF558E A Simple Task的主要内容,如果未能解决你的问题,请参考以下文章

[CF558E]A Simple Task

CF558E A Simple Task

CF558E A Simple Task

CF558E A Simple Task 线段树

Codeforces 558E A Simple Task

Codeforces 558E A Simple Task