zoukankan      html  css  js  c++  java
  • (线段树区间赋值)CSU 1942

    题意:

    一个串(串中只有26个小写字母),选一个区间进行排序,进行100000次,输出最后的串。

    分析:

    比赛的时候很懵逼,感觉这题跟之前的额大崩龙有点像,但是没多想,也怪自己太菜了。

    确实是真的像,甚至是一模一样啊。

    对于每次排序只需要进行一次类似计数排序的的操作即可,26个字符,进行26次区间赋值即可。理论上时间能过得去。

    代码:

      1 #include <queue>
      2 #include <string>
      3 #include <cstdio>
      4 #include <cstring>
      5 #include <iostream>
      6 #include <algorithm>
      7 #include <map>
      8 
      9 
     10 using namespace     std;
     11 
     12 typedef long long ll;
     13 typedef unsigned long long ull;
     14 typedef pair<int, int> pii;
     15 typedef pair<ull, ull> puu;
     16 
     17 #define inf (0x3f3f3f3f)
     18 #define lnf (0x3f3f3f3f3f3f3f3f)
     19 #define eps (1e-8)
     20 #define fi first
     21 #define se second
     22 
     23 //--------------------------
     24 
     25 const ll mod = 1000000007;
     26 const int maxn = 100010;
     27 
     28 
     29 char str[maxn];
     30 int n;
     31 int q;
     32 
     33 struct Node {
     34     int left, right;
     35     int num[26];
     36     int lazy;
     37 } node[maxn << 2];
     38 
     39 void push_up(int n) {
     40     for(int i = 0; i < 26; i++) {
     41         node[n].num[i] = node[n << 1].num[i] + node[n << 1 | 1].num[i];
     42     }
     43 }
     44 
     45 void push_down(int n) {
     46     if(node[n].lazy != -1) {
     47         node[n << 1].lazy = node[n << 1 | 1].lazy = node[n].lazy;
     48         memset(node[n << 1].num, 0, sizeof(node[n << 1].num));
     49         memset(node[n << 1 | 1].num, 0, sizeof(node[n << 1 | 1].num));
     50         node[n << 1].num[node[n].lazy] = (node[n].right - node[n].left + 1) - (node[n].right - node[n].left + 1) / 2;
     51         node[n << 1 | 1].num[node[n].lazy] = (node[n].right - node[n].left + 1) / 2;
     52         node[n].lazy = -1;
     53     }
     54 }
     55 
     56 void update(int n, int left, int right, char val) {
     57     if(node[n].left >= left && node[n].right <= right) {
     58         node[n].lazy = val - 'a';
     59         memset(node[n].num, 0, sizeof(node[n].num));
     60         node[n].num[node[n].lazy] = node[n].right - node[n].left + 1;
     61         return ;
     62     }
     63     push_down(n);
     64     int mid = (node[n].left + node[n].right) >> 1;
     65     if(mid >= left)update(n << 1, left, right, val);
     66     if(mid < right)update(n << 1 | 1, left, right, val);
     67     push_up(n);
     68 }
     69 
     70 int query(int n, int left, int right, char val) {
     71     if(node[n].left >= left && node[n].right <= right) {
     72         return node[n].num[val - 'a'];
     73     }
     74     push_down(n);
     75     int mid = (node[n].left + node[n].right) >> 1;
     76     int sum = 0;
     77     if(mid >= left)sum += query(n << 1, left, right, val);
     78     if(mid < right)sum += query(n << 1 | 1, left, right, val);
     79     return sum;
     80 }
     81 
     82 
     83 void build(int n, int left, int right) {
     84     node[n].left = left;
     85     node[n].right = right;
     86     node[n].lazy = -1;
     87     if(left == right) {
     88         node[n].num[str[left] - 'a'] = 1;
     89         return ;
     90     }
     91     int mid = (left + right) >> 1;
     92     build(n << 1, left, mid);
     93     build(n << 1 | 1, mid + 1, right);
     94     push_up(n);
     95 }
     96 
     97 void print(int n) {
     98     if(node[n].left == node[n].right) {
     99         for(int i = 0; i < 26; i++) {
    100             if(node[n].num[i] != 0) {
    101                 printf("%c", i + 'a');
    102                 break;
    103             }
    104         }
    105         return ;
    106     }
    107     push_down(n);
    108     print(n << 1);
    109     print(n << 1 | 1);
    110 }
    111 
    112 void solve() {
    113     while(~scanf("%d%d", &n, &q)) {
    114         memset(node, 0, sizeof(node));
    115         scanf("%s", str + 1);
    116         build(1, 1, n);
    117         while(q--) {
    118             int l, r, op;
    119             scanf("%d%d%d", &l, &r, &op);
    120             int num[26] = {0};
    121             for(int i = 0; i < 26; i++) {
    122                 num[i] = query(1, l, r, i + 'a');
    123             }
    124             if(op == 1) {
    125                 for(int i = 0; i < 26; i++) {
    126                     if(num[i] > 0) {
    127                         update(1, l, l + num[i] - 1, i + 'a');
    128                         l += num[i];
    129                     }
    130                 }
    131             } else {
    132                 for(int i = 25; i >= 0; i--) {
    133                     if(num[i] > 0) {
    134                         update(1, l, l + num[i] - 1, i + 'a');
    135                         l += num[i];
    136                     }
    137                 }
    138             }
    139         }
    140         print(1);
    141         puts("");
    142     }
    143 
    144 
    145 
    146 }
    147 
    148 int main() {
    149 #ifndef ONLINE_JUDGE
    150     freopen("1.in", "r", stdin);
    151     freopen("1.out", "w", stdout);
    152 #endif
    153     solve();
    154     return 0;
    155 }
  • 相关阅读:
    PHP代码审计学习(7)——XSS漏洞
    PHP代码审计学习(6)——命令执行
    PHP代码审计学习(5)——代码执行漏洞
    PHP代码审计学习(4)——SQL漏洞
    PHP代码审计学习(3)——常见的超全局变量
    PHP代码审计学习(2)——php.ini核心配置
    关于Backus-Naur Form巴克斯诺尔范式和扩展巴克斯范式的知识点和相关词语中英文对照
    Python对列表的相关操作(与JAVA对比)
    MergeSort归并排序和利用归并排序计算出数组中的逆序对
    统计字符串中每种字符出现的评率(HashMap中getOrDefault(K, V)方法的使用)
  • 原文地址:https://www.cnblogs.com/tak-fate/p/6965329.html
Copyright © 2011-2022 走看看