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 ...
随机推荐
- 想学渗透测试,应该考CISP-PTE还是NISP-PT?|网安伴nisp和cisp
其实两者都可,但要看考生的实际需求! 为什么说两者都可以? 两个证书都由中国信息安全测评中心颁发,CISP-PTE全称国家注册渗透测试工程师,NISP-PT全称国家信息安全水平考试-渗透测试工程师专项 ...
- 【漏洞分析】KaoyaSwap 安全事件分析
相关信息 KaoyaSwap 是 BSC 链上的一个自动做市商 AMM.然后,现在他们的官网 https://www.kaoyaswap.com/ 已经打不开了(如果我打开方式没错的话).所以就直接进 ...
- Qt QBarSeries简易柱状图教程
博客园最强Qt QBarSeries简易柱状图教程 前情提要 每个人的绘图需求不同,此篇教程也是根据需求来改的.我的需求大概如下所示. 通过信号槽的方式接收signals来刷新柱状图,所以每次触发信号 ...
- 在 node 中使用 jquery ajax
对于前端同学来说,ajax 请求应该不会陌生.jquery 真的ajax请求做了封装,可以通过下面的方式发送一个请求并获取相应结果: $.ajax({ url: "https://echo. ...
- 第十四章 二进制部署k8s集群的平滑升级
1.软件包下载 去github上下载较新的Kubernetes软件包https://github.com/ 2.升级说明 升级包括master节点升级和node节点的升级,本章升级至v1.15.12: ...
- KingbaseES V8R6备份恢复案例之---同一数据库创建不同stanza备份
案例说明: 在生产环境,有的应用需要调用数据库的sys_rman做备份,为了区分数据库自身的sys_rman备份和应用的备份,可以使用不同的stanza name创建备份.本案例介绍了,如何在King ...
- bean的作用域解析
说明 意义 1.在Spring中,Bean的作用域可以通过scope属性来指定. 2.指定作用域的目的是 存储在此类单例bean的高速缓存中,并且对该命名bean的所有后续请求和引用都返回该高速 ...
- 国产PLM软件在创新实践中强势崛起
近日,"璞华PLM"先后获得微度医疗.埃特斯等多个客户的订单,即使在疫情环境下也展现出了强劲的高速增长.在产品生命周期管理(PLM,Product Lifecycle Manage ...
- 使用Watchtower实现Docker容器自动更新
前言:通常情况下我们手动更新容器的步骤比较繁琐,需要四个步骤: 1.停止容器 2.删除容器 3.检查镜像更新情况,更新镜像 4.重新启动容器 容器少还无所谓,但要是需要更新大量的容器就会工作量巨大. ...
- C#-1 .Net框架
一 .Net框架组成分为三部分:公共语言运行时CLR.框架类库FCL和编程工具 1.CLR:公共语言运行时(Common Language Runtime): 是一个运行时环境负责代码安全验证.代码执 ...