zoukankan      html  css  js  c++  java
  • 【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;
    }
    
    
  • 相关阅读:
    浅谈python socket编程
    MYSQL(三)
    python数据库操作之pymysql模块和sqlalchemy模块(项目必备)
    MYSQL(二)
    ajax应用篇
    浅析tornado web框架
    CSS学习笔记06 简单理解line-height
    CSS学习笔记05 display属性
    CSS学习笔记04 CSS文字排版常用属性
    CSS学习笔记03 CSS层叠性、继承性、特殊性
  • 原文地址:https://www.cnblogs.com/Qihoo360/p/9784120.html
Copyright © 2011-2022 走看看