(线段树区间赋值)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_JUDGE
150     freopen("1.in", "r", stdin);
151     freopen("1.out", "w", stdout);
152 #endif
153     solve();
154     return 0;
155 }
时间: 2024-10-15 03:04:35

(线段树区间赋值)CSU 1942 - Sort String的相关文章

HDU 5316 Magician(线段树区间合并入门)

本文纯属原创,转载请注明出处谢谢.http://blog.csdn.net/zip_fan. 题目传送门:http://acm.hdu.edu.cn/showproblem.php?pid=5316 Time Limit: 18000/9000 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Others) Problem Description Fantasy magicians usually gain their ability

线段树区间更新

区间更新也可以分割成若干个子区间, 每层的结点至多选取 2 个,时间复杂度 O(logn). 懒惰(Lazy)标记 懒惰标记,也可称为延迟标记.一个区间可以转化为若干个结点,每个结点设一个标记,记录这个结点被进行了某种修改操作(这种修改操作会影响其子结点). 也就是说,仅修改到这些结点,暂不修改其子结点:而后决定访问其子节点时,再下传懒惰 (Lazy) 标记,并消除原来的标记. 优点在于,不用将区间的所有值暴力更新,大大提高效率. 在区间修改的一类问题中,我们可以设一个 delta 域,表示该节

线段树 区间更新

poj3468 A Simple Problem with Integers ( m - ( m >> 1 ) )这里跪了几发.. - 的优先级大于 >> 1 #include<iostream> 2 #include<cstring> 3 #include<algorithm> 4 #include<cstdio> 5 #include<string> 6 #include<queue> 7 #include

线段树 + 区间更新 + 模板 ---- poj 3468

A Simple Problem with Integers Time Limit: 5000MS   Memory Limit: 131072K Total Submissions: 59798   Accepted: 18237 Case Time Limit: 2000MS Description You have N integers, A1, A2, ... , AN. You need to deal with two kinds of operations. One type of

线段树+区间离散化

校赛1007 题意 给你一个n(n<1e5),表示n个比赛直播,然后n个区间,l,r(0<=l,r<=1e9),表示比赛开始的时间和结束的时间,要同时把所有比赛看完,问最少要借多少台电脑(自己有一台电脑) 其实就是求区间重叠的最大值由于区间太大,所以离散化处理 思路:线段树区间更新 + 离散化 以区间的端点作为标记离散化,离散化后映射到线段树,将重复的端点去掉,然后重新排序,对每个区间二分确定映射后的区间,这里注意二分的时候左端点和右端点二分的判断条件是不同的 AC代码: #includ

POJ 2528——Mayor&#39;s posters——————【线段树区间替换、找存在的不同区间】

Mayor's posters Time Limit:1000MS     Memory Limit:65536KB     64bit IO Format:%I64d & %I64u Submit Status Practice POJ 2528 Description The citizens of Bytetown, AB, could not stand that the candidates in the mayoral election campaign have been plac

POJ 2528 Mayor&#39;s posters(线段树区间染色+离散化或倒序更新)

Mayor's posters Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 59239   Accepted: 17157 Description The citizens of Bytetown, AB, could not stand that the candidates in the mayoral election campaign have been placing their electoral post

poj-----(2528)Mayor&#39;s posters(线段树区间更新及区间统计+离散化)

Mayor's posters Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 43507   Accepted: 12693 Description The citizens of Bytetown, AB, could not stand that the candidates in the mayoral election campaign have been placing their electoral post

hdu 5023 A Corrupt Mayor&#39;s Performance Art (线段树+区间更新+状压)

A Corrupt Mayor's Performance Art Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 100000/100000 K (Java/Others) Total Submission(s): 699    Accepted Submission(s): 267 Problem Description Corrupt governors always find ways to get dirty money.