码迷,mamicode.com
首页 > 其他好文 > 详细

【CF558E】 A Simple Task

时间:2018-10-13 21:44:27      阅读:300      评论:0      收藏:0      [点我收藏+]

标签:print   ems   max   set   http   ref   时间   codeforce   const   

题目链接
用权值线段树维护每个字母在\([l,r]\)出现的次数,每次修改把每个字母在区间的出现次数记下来,然后清空这段区间,再按顺序插进去就好了。
时间复杂度\(O(n\log 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

标签:print   ems   max   set   http   ref   时间   codeforce   const   

原文地址:https://www.cnblogs.com/Qihoo360/p/9784120.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!