【CF558E】 A Simple Task (权值线段树)
题目链接
用权值线段树维护每个字母在\([l,r]\)出现的次数,每次修改把每个字母在区间的出现次数记下来,然后清空这段区间,再按顺序插进去就好了。
时间复杂度\(O(n\log 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;
}
【CF558E】 A Simple Task (权值线段树)的更多相关文章
- Codeforces 558E A Simple Task(权值线段树)
题目链接 A Simple Task 题意 给出一个小写字母序列和若干操作.每个操作为对给定区间进行升序排序或降序排序. 考虑权值线段树. 建立26棵权值线段树.每次操作的时候先把26棵线段树上的 ...
- D. Restore Permutation(权值线段树)
D. Restore Permutation time limit per test 2 seconds memory limit per test 256 megabytes input stand ...
- 【树状数组套权值线段树】bzoj1901 Zju2112 Dynamic Rankings
谁再管这玩意叫树状数组套主席树我跟谁急 明明就是树状数组的每个结点维护一棵动态开结点的权值线段树而已 好吧,其实只有一个指针,指向该结点的权值线段树的当前结点 每次查询之前,要让指针指向根结点 不同结 ...
- 【BZOJ-2892&1171】强袭作战&大sz的游戏 权值线段树+单调队列+标记永久化+DP
2892: 强袭作战 Time Limit: 50 Sec Memory Limit: 512 MBSubmit: 45 Solved: 30[Submit][Status][Discuss] D ...
- BZOJ 3110 ZJOI 2013 K大数查询 树套树(权值线段树套区间线段树)
题目大意:有一些位置.这些位置上能够放若干个数字. 如今有两种操作. 1.在区间l到r上加入一个数字x 2.求出l到r上的第k大的数字是什么 思路:这样的题一看就是树套树,关键是怎么套,怎么写.(话说 ...
- 动态求区间K大值(权值线段树)
我们知道我们可以通过主席树来维护静态区间第K大值.我们又知道主席树满足可加性,所以我们可以用树状数组来维护主席树,树状数组的每一个节点都可以开一颗主席树,然后一起做. 我们注意到树状数组的每一棵树都和 ...
- 线段树(单标记+离散化+扫描线+双标记)+zkw线段树+权值线段树+主席树及一些例题
“队列进出图上的方向 线段树区间修改求出总量 可持久留下的迹象 我们 俯身欣赏” ----<膜你抄> 线段树很早就会写了,但一直没有总结,所以偶尔重写又会懵逼,所以还是要总结一下. ...
- 【BZOJ3685】【zkw权值线段树】普通van Emde Boas树
原题传送门 因为马上要开始搞树套树了,所以学了一波权值线段树...毕竟是会点zkw线段树的,所以zkw线段树大法好! 解题思路: 介绍一下权值线段树吧,其实感觉就是线段树的本义,就是你用线段树维护了数 ...
- BZOJ_2161_布娃娃_权值线段树
BZOJ_2161_布娃娃_权值线段树 Description 小时候的雨荨非常听话,是父母眼中的好孩子.在学校是老师的左右手,同学的好榜样.后来她成为艾利斯顿第二 代考神,这和小时候培养的良好素质是 ...
- BZOJ_3685_普通van Emde Boas树_权值线段树
BZOJ_3685_普通van Emde Boas树_权值线段树 Description 设计数据结构支持: 1 x 若x不存在,插入x 2 x 若x存在,删除x 3 输出当前最小值,若不存 ...
随机推荐
- 在LaTex中插入电路图的方法(插入图片)
主要的需求是要在文档中插入电路图. 有两种方法,一种是直接在LaTex中绘制电路图,使用的库主要是circ和circuitikz 另一种是在其他软件上绘制电路图,转成特定图像格式后,在Latex中插入 ...
- 实验吧密码学:RSAROLL
原题: {920139713,19} 704796792 752211152 274704164 18414022 368270835 483295235 263072905 459788476 48 ...
- 修改QQ各版本的默认保存位置(聊天记录)
这几天没少折腾windows,都有点烦了,我是那种有强迫症的,只要知道的自己没有做到的会感觉到浑身不爽的因为系统重装了好几次,QQ也没少安装几次,我使用的是TM的QQ(没有 那么多烦人的广告,娱乐组件 ...
- [C/C++] C/C++错题集
1. 解析: A:在GCC下输出:0 在VC6.0下输出:1 B:在GCC下输出:段错误 (核心已转储) 在VC6.0下输出:已停止工作,出现了一个问题,导致程序停止正常工作. C:正常 ...
- Spring Boot 最简单的HelloWorld
创建一个Spring Boot,可以直接使用构建工具(Maven或Gradle)创建,也可以使用spring.io网站创建,一般会选择使用spring.io创建 使用IDEA创建一个Spring Bo ...
- bzoj2676 Contra
题意: 给定N,R,Q,S 有N个关卡,初始有Q条命,且任意时刻最多只能有Q条命 每通过一个关卡,会得到u分和1条命,其中u=min(最近一次连续通过的关数,R) 若没有通过这个关卡,将失去一条命,并 ...
- Luogu3147 USACO16OPEN 262144(动态规划)
感觉上这个题是可以直接暴力的,每次根据一段连续最小值个数的奇偶性决定是否划分区间,递归处理.然而写起来实在太麻烦了. 设f[i][j]为以i为左端点合并出j时的右端点.则有f[i][j]=f[f[i] ...
- 【题解】CF#280 C-Game on Tree
感觉对期望也一无所知……(:′⌒`)╮(╯﹏╰)╭ 一直在考虑怎么dp,最后看了题解——竟然是这样的???[震惊]但是看了题解之后,觉得确实很有道理…… 我们可以考虑最后答案的组成,可以分开计算不同的 ...
- [洛谷P1369]矩形
题目大意:有$n(n\leqslant300)$个点,每个点坐标范围在$[1\sim100]$,求一个矩阵,使得边界上的点最多. 题解:做一遍二维前缀和,直接暴力枚举两个顶点 卡点:无 C++ Cod ...
- [洛谷P4070][SDOI2016]生成魔咒
题目大意:有一个字符串,每次在末尾加入一个字符,问当前共有多少个本质不同的字串 题解:$SAM$,就是问插入这个字符后,多了多少个字串,就是当前这个点的$Right$数组大小. 卡点:无 C++ Co ...