首页 > 代码库 > (线段树区间赋值)CSU 1942 - Sort String

(线段树区间赋值)CSU 1942 - Sort String

题意:

一个串(串中只有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_JUDGE150     freopen("1.in", "r", stdin);151     freopen("1.out", "w", stdout);152 #endif153     solve();154     return 0;155 }

 

(线段树区间赋值)CSU 1942 - Sort String