CF240F (26颗线段树计数)
题目链接:Topcoder----洛谷
题目大意:
给定一个长为n的由a到z组成的字符串,有m次操作,每次操作将[l,r]这些位置的字符进行重排,得到字典序最小的回文字符串,如果无法操作就不进行。
思路:
用26颗线段树分别统计在每个位置上是否有对应的字母
每次操作:
1.有出现次数为奇数的字母:
大于1,不可能回文,无法操作。
等于1,放到中间
2.全是偶数次数:
分别放两端
1 # include<bits/stdc++.h>
2 using namespace std;
3 #define endl "\n"
4 # define int long long
5 # define ls u<<1
6 # define rs u<<1|1
7 const int N = 1e5 + 10;
8 char a[N], p;
9 int n, m;
10 struct segtree {
11 int sum[4 * N], lazy[4 * N];
12 void pushup(int u) {
13 sum[u] = (sum[ls] + sum[rs]);
14 }
15
16 void build(int tr, int u, int l, int r) {
17 lazy[u] = -1;
18 if (l == r) {
19 sum[u] = ((a[l] - 'a' ) == tr);
20 return;
21 }
22 int mid = l + r >> 1;
23 build(tr, ls, l, mid);
24 build(tr, rs, mid + 1, r);
25 pushup(u);
26 }
27
28 void pushdown(int u, int l, int r) {
29 int mid = l + r >> 1;
30 if (lazy[u] != -1) {
31 sum[ls] = (mid - l + 1) * lazy[u];
32 sum[rs] = (r - mid) * lazy[u];
33
34 lazy[ls] = lazy[u];
35 lazy[rs] = lazy[u];
36 lazy[u] = -1;
37 }
38
39 }
40
41 void modify(int u, int l, int r, int L, int R, int c) {
42 if (l > r || l > R || r < L) return;
43 if (L <= l && r <= R) {
44 sum[u] = (r - l + 1) * c;
45 lazy[u] = c;
46 return;
47 }
48 int mid = l + r >> 1;
49 pushdown(u, l, r);
50 if (L <= mid) modify(ls, l, mid, L, R, c);
51 if (mid + 1 <= R) modify(rs, mid + 1, r, L, R, c);
52 pushup(u);
53 }
54
55 int query(int u, int l, int r, int L, int R) {
56 if (l > r || l > R || r < L) return 0;
57 if (l >= L && r <= R) {
58 return sum[u];
59 }
60 pushdown(u, l, r);
61 int mid = l + r >> 1;
62 int ans = 0;
63 if (L <= mid) ans += query(ls, l, mid, L, R);
64 if (R > mid) ans += query(rs, mid + 1, r, L, R);
65 return ans;
66 }
67 } tr[26];
68
69 signed main() {
70 ios::sync_with_stdio(false);
71 cin.tie(0);
72 cout.tie(0);
73 freopen("input.txt", "r", stdin);
74 freopen("output.txt", "w", stdout);
75 cin >> n >> m;
76 string s;
77 cin >> s;
78 for (int i = 1; i <= n; ++i) a[i] = s[i - 1];
79 for (int i = 0; i < 26; ++i) tr[i].build(i, 1, 1, n);
80 for (int t = 1; t <= m; ++t) {
81 int l, r;
82 cin >> l >> r;
83 int odd = 0;
84 int tmp[26] = {0}, key;
85 for (int i = 0; i < 26; ++i) tmp[i] = tr[i].query(1, 1, n, l, r);//记录在区间[l,r]中每个字母出现的次数
86 for (int i = 0; i < 26; ++i) if (tmp[i] & 1) odd++, key = i;
87 if (odd > 1) continue;
88 for (int i = 0; i < 26; ++i) tr[i].modify(1, 1, n, l, r, 0);
89 if (odd) {
90 --tmp[key];
91 tr[key].modify(1, 1, n, (l + r) / 2, (l + r) / 2, 1);//奇数置中
92 }
93 int nl = l, nr = r;
94 for (int i = 0; i < 26; ++i) {//偶数分两边放
95 if (tmp[i]) {
96 tr[i].modify(1, 1, n, nl, nl + tmp[i] / 2 - 1, 1);
97 nl += tmp[i] / 2;
98 tr[i].modify(1, 1, n, nr - tmp[i] / 2 + 1, nr, 1);
99 nr -= tmp[i] / 2;
100 }
101 }
102 }
103 for (int i = 1; i <= n; ++i) {
104 for (int j = 0; j < 26; ++j) {
105 if (tr[j].query(1, 1, n, i, i)) {
106 cout << (char)(j + 'a');
107 }
108 }
109 }
110 return 0;
111 }
CF240F (26颗线段树计数)的更多相关文章
- Codeforces Round #312 (Div. 2) E. A Simple Task 线段树+计数排序
题目链接: http://codeforces.com/problemset/problem/558/E E. A Simple Task time limit per test5 secondsme ...
- Codeforces 588E. A Simple Task (线段树+计数排序思想)
题目链接:http://codeforces.com/contest/558/problem/E 题意:有一串字符串,有两个操作:1操作是将l到r的字符串升序排序,0操作是降序排序. 题解:建立26棵 ...
- ACM-ICPC 2018 徐州赛区网络预赛 G Trace(逆向,两颗线段树写法)
https://nanti.jisuanke.com/t/31459 思路 凡是后面的轨迹对前面的轨迹有影响的,可以尝试从后往前扫 区间修改需要push_down,单点更新所以不需要push_up(用 ...
- HDU 4267 A Simple Problem with Integers(2012年长春网络赛A 多颗线段树+单点查询)
以前似乎做过类似的不过当时完全不会.现在看到就有点思路了,开始还有洋洋得意得觉得自己有不小的进步了,结果思路错了...改了很久后测试数据过了还果断爆空间... 给你一串数字A,然后是两种操作: &qu ...
- HDU 3954 Level up(多颗线段树+lazy操作)
又是一开始觉得的水题,结果GG了好久的东西... 题意是给你n个英雄,每个英雄开始为1级经验为0,最多可以升到k级并且经验一直叠加,每一级都有一个经验值上限,达到就升级.接着给你两种操作:W li r ...
- CF 85D Sum of Medians (五颗线段树)
http://codeforces.com/problemset/problem/85/D 题意: 给你N(0<N<1e5)次操作,每次操作有3种方式, 1.向集合里加一个数a(0< ...
- Codeforces - 240F 是男人就上26棵线段树
#include<bits/stdc++.h> using namespace std; const int maxn = 1e5+11; typedef long long ll; ch ...
- Codeforces 558E A Simple Task(计数排序+线段树优化)
http://codeforces.com/problemset/problem/558/E Examples input 1 abacdabcda output 1 cbcaaaabdd input ...
- CF558E-A Simple Task-线段树+计数排序
计数排序的原理,只要知道了有几个数比i小,就可以知道i的位置 这道题只有26个字母,搞26颗线段树,然后区间更新 #include <cstdio> #include <cstrin ...
随机推荐
- 我就获取个时间,机器就down了
本文主要讲解linux 时间管理系统中的一个问题 背景:linux 时间管理,包含clocksource,clockevent,timer,tick,timekeeper等等概念 , 这些概念有机地组 ...
- 爬虫简介与excel表格操作
爬虫简介与excel表格操作 re模块简介 1.在python中使用正则表达式的话那么re模块就是选择之一 import re # 导入re模块 2.在re模块中使用findall找到所有我们给他的值 ...
- 实时降噪(Real-time Denoising):Spatio-Temporal Filtering
目录 空间滤波(Spatial Filtering) 基于距离的高斯滤波 双边滤波(Bilateral filtering) 联合双边滤波(Joint Bilateral filtering)[201 ...
- 【面试题】JS使用parseInt()、正则截取字符串中数字
JS使用parseInt()和正则截取字符串中数字 点击打开视频讲解更加详细 parseInt() 函数 定义和用法 parseInt() 函数可解析一个字符串,并返回一个整数. 当参数 radix ...
- VSCODE 配置远程调试环境
以下内容为本人的著作,如需要转载,请声明原文链接微信公众号「englyf」https://www.cnblogs.com/englyf/p/16691460.html 我的需求是,在Windows桌面 ...
- HashMap不安全后果及ConcurrentHashMap线程安全原理
Java集合HashMap不安全后果及ConcurrentHashMap 原理 目录 HashMap JDK7 HashMap链表循环造成死循环 HashMap数据丢失 JDK7 Concurrent ...
- Nessus-8.11.1-x64.msi安装包
希望能给那些和我一样迷茫受挫的小伙伴们一些帮助,这玩意儿下载挺慢的,我把安装包分享出来,如果有博客园账号的,点个赞呗,CSDN那些用着别人的软件还要积分,呸! 08-18更新,截止到现在,已更新到最新 ...
- Kubernetes DevOps: Harbor
Harbor 是一个 CNCF 基金会托管的开源的可信的云原生 docker registry 项目,可以用于存储.签名.扫描镜像内容,Harbor 通过添加一些常用的功能如安全性.身份权限管理等来扩 ...
- catalina.out日志割接
文章转载自:https://blog.51cto.com/loong576/2091460 Tomcat的catalina.out日志分割有多种方式,如logrotate.cronolog等,本文采用 ...
- (WebFlux)004、WebFilter踩坑记录
一.背景 使用SpringWebFlux的WebFilter时,由于不熟悉或一些思考疏忽,容易出现未知的异常.记录一下排查与解决方案,给大家分享一下. 二.问题 2.1 问题描述 在测试接口方法时,出 ...