zoukankan      html  css  js  c++  java
  • CF#312 558e A Simple Task

    ~~~题面~~~

    题解:

      观察到字母只有26个,因此考虑对这26个字母分别维护,每个线段树维护一个字母,如果一个线段树的某个叶节点有值,表示当前叶节点所在位置的字母是现在这个线段树代表的字母。

      那么对于每一个操作,我们已经知道最后排好序之后肯定是按aaaabbbbccccddd……这样的序列排下去的(有些字母可能没有),每个字母都集中在自己的区间内。

      那么我们只需要知道每个字母之前的字母有多少个,就可以知道这个字母所在区间,因此按顺序修改。

      (以下操作均视为在每个字母对应的线段树上操作)先查询a的个数,并把当前修改的区间内赋0,然后把前1~tot_a全都赋1,表示这段区间是属于a的(全都放上1)。

      记在统计当前字母之前找到的字母个数之和为tot,则每次都是把当前线段树管理的字母全都移动到tot + 1~tot + 字母个数,相当于跟修改a类似的区间操作。只不过属于这个字母的区间的开始端点是tot + 1(其实a的情况也可以视作是tot + 1,因为这个时候tot = 0)

      1 #include<bits/stdc++.h>
      2 using namespace std;
      3 #define R register int
      4 #define LL long long
      5 #define AC 101000
      6 #define ac 401000
      7 
      8 int n, m, id, tot, add, t;
      9 int l[ac], r[ac];
     10 char s[AC], ans[AC];
     11 
     12 int read()
     13 {
     14     int x = 0;char c = getchar();
     15     while(c > '9' || c < '0') c = getchar();
     16     while(c >= '0' && c <= '9') x = x * 10 + c -'0', c = getchar();
     17     return x;
     18 }
     19 
     20 inline void upmin(int &a, int b)
     21 {
     22     if(b < a) a = b;
     23 }
     24 
     25 inline void upmax(int &a, int b)
     26 {
     27     if(b > a) a = b;
     28 }
     29 
     30 struct segament_tree{
     31     int tree[ac], lazy[ac], id;
     32     
     33     inline void init()
     34     {
     35         memset(lazy, -1, sizeof(lazy));
     36     }
     37     
     38     inline void update(int x)
     39     {
     40         tree[x] = tree[x * 2] + tree[x * 2 + 1];
     41     }
     42     
     43     inline void pushdown(int x)
     44     {
     45         if(lazy[x] != -1)
     46         {
     47             int ll = x * 2, rr = ll + 1;
     48             lazy[ll] = lazy[rr] = lazy[x];
     49             if(!lazy[x]) tree[ll] = tree[rr] = 0;
     50             else
     51             {
     52                 int mid = (l[x] + r[x]) >> 1;
     53                 tree[ll] = mid - l[ll] + 1;
     54                 tree[rr] = r[rr] - mid;
     55             }
     56             lazy[x] = -1;
     57         }
     58     }
     59     
     60     void build(int x, int ll, int rr)
     61     {
     62         if(!id) l[x] = ll, r[x] = rr;
     63         if(ll == rr) 
     64         {
     65             if(s[ll] == id + 'a') tree[x] = 1;
     66             return ;
     67         }
     68         int mid = (ll + rr) >> 1;
     69         build(x * 2, ll, mid);
     70         build(x * 2 + 1, mid + 1, rr);
     71         update(x);
     72     }
     73     
     74     void find(int x, int ll, int rr)
     75     {
     76         if(!tree[x]) return ;
     77         if(l[x] == ll && r[x] == rr){add += tree[x]; return ;}
     78         pushdown(x);
     79         int mid = (l[x] + r[x]) >> 1;
     80         if(rr <= mid) find(x * 2, ll, rr);
     81         else if(ll > mid) find(x * 2 + 1, ll, rr);
     82         else
     83         {
     84             find(x * 2, ll, mid);
     85             find(x * 2 + 1, mid + 1, rr);
     86         }
     87         update(x);
     88     }
     89     
     90     void change(int x, int ll, int rr)
     91     {
     92         if(l[x] == ll && r[x] == rr)
     93         {
     94             lazy[x] = t;
     95             if(t) tree[x] = rr - ll + 1;
     96             else tree[x] = 0;
     97             return ;
     98         }    
     99         pushdown(x);
    100         int mid = (l[x] + r[x]) >> 1;
    101         if(rr <= mid) change(x * 2, ll, rr);
    102         else if(ll > mid) change(x * 2 + 1, ll, rr);
    103         else
    104         {
    105             change(x * 2, ll, mid);
    106             change(x * 2 + 1, mid + 1, rr);
    107         }
    108         update(x);
    109     }
    110 
    111     void get(int x)
    112     {
    113         if(!tree[x]) return ;
    114         if(tree[x] == r[x] - l[x] + 1)
    115         {
    116             for(R i = l[x]; i <= r[x]; i ++) ans[i] = id + 'a';
    117             return ;
    118         }
    119         pushdown(x);
    120         if(tree[x * 2]) get(x * 2);
    121         if(tree[x * 2 + 1]) get(x * 2 + 1);
    122     }
    123 
    124 }T[26];
    125 
    126 void pre()
    127 {
    128     n = read(), m = read();
    129     scanf("%s", s + 1);
    130     for(R i = 0; i < 26; i ++) 
    131         T[i].id = i, T[i].init(), T[i].build(1, 1, n);
    132 }
    133 
    134 void check()
    135 {
    136     for(R i = 0; i < 26; i ++) T[i].get(1);
    137     for(R i = 1; i <= n; i ++) printf("%c", ans[i]);
    138     printf("
    ");
    139 }
    140 
    141 void work()
    142 {
    143     int ll, rr, opt;
    144     for(R i = 1; i <= m; i ++)
    145     {
    146     //    printf("%d
    ", i);
    147         ll = read(), rr = read(), opt = read(), tot = ll - 1;
    148         if(opt)
    149         {
    150             for(R j = 0; j < 26; j ++)
    151             {
    152                 add = t = 0;
    153                 T[j].find(1, ll, rr);
    154                 if(!add) continue;
    155                 T[j].change(1, ll, rr);
    156                 t = 1;
    157                 T[j].change(1, tot + 1, tot + add);
    158                 tot += add;
    159             }
    160             //check();
    161         }
    162         else
    163         {
    164             for(R j = 25; j >= 0; j --)
    165             {
    166                 add = t = 0;
    167                 T[j].find(1, ll, rr);
    168                 if(!add) continue;
    169                 T[j].change(1, ll, rr);
    170                 t = 1;
    171                 T[j].change(1, tot + 1, tot + add);
    172                 tot += add;
    173             }
    174         //    check();
    175         }
    176     }
    177     for(R i = 0; i < 26; i ++) T[i].get(1);
    178     for(R i = 1; i <= n; i ++) printf("%c", ans[i]);
    179     printf("
    ");
    180 }
    181 
    182 int main()
    183 {
    184     //freopen("string6.in", "r", stdin);
    185     pre();
    186     work();
    187     //fclose(stdin);
    188     return 0;
    189 }
    View Code
  • 相关阅读:
    RTSP/GB28181/HIKSDK/Ehome协议视频平台EasyCVR预览流添加自定义信息方法介绍
    RTSP/GB28181/HIKSDK/Ehome协议视频上云服务平台EasyCVR人脸识别开发ArcSoftFace环境搭建
    如何在同一系统的电脑中同时启动2个不同版本的RTSP协议网页无插件直播视频平台EasyNVR?
    RTSP网络摄像头网页无插件直播视频平台EasyNVR自定义标题和CopyRight步骤
    H265网页视频播放器播放录像时间轴与实际视频时间不相符如何处理?
    【方案搭建】搭建智慧工厂实时视频监控系统有哪些方式?国标平台EasyGBS及EasyCVR平台对比
    如何在RTSP协议网页无插件直播流媒体视频平台EasyNVR演示系统内做到自定义断流?
    【解决方案】RTSP协议网页无插件直播视频平台EasyNVR如何通过CDN连通内外网实现连锁餐饮企业远程监控管理系统?
    RTSP协议网络摄像头网页无插件直播流媒体服务器平台EasyNVR显示视频不在线如何排查?
    数据库应用系统功能设计与实施
  • 原文地址:https://www.cnblogs.com/ww3113306/p/9847478.html
Copyright © 2011-2022 走看看