校赛F 比比谁更快(线段树)
http://acm.cug.edu.cn/JudgeOnline/problem.php?cid=1153&pid=5
题意:给你一个字符串,各两个操作:
ch=0,[l,r]降序
ch=1,[l,r]升序
如果是newer的话,应该会想用暴力,直接对区间sort,但是很明显是超时的(校赛怎么会这么简单呢!)
很容易想到线段数,对于线段数,我们可以先理清一下知识点,线段树大概有三种操作:
- 单点更新
- 区间更新
- RMQ
显然这里要用区间更新的操作。
区间更新有三大操作:
build()建树
update()更新
query()求和
sum[4*N]存储线段数节点
但是一般的区间更新的线段数是区间加或者区间减等统一的操作,所以对于区间排序需要对区间查询模板更改一下。
sum[4*N][26]来存储线段数节点
setv[4*N]来存储当前区间覆盖的字母
cnt[26]表示每个字母在当前区间出现的次数
下面以样例“abacdabcda”为例进行阐述:
首先是建树过程:
这一部分计算出sum[4N][26]和setv[4N]的值
其次,对于每一个查询,“l,r,ch”
都要用query(int rt,int L,int R,int l,int r,int i)计算[l,r]区间cnt[i]的值。
最后一步,对于每一个查询”l,r,ch”
根据ch的值:
做update(int rt,int L,int R,int l,int r,int i)
如果ch=0,对[l,r]降序
做法是:对cnt[i]数组从25->0 遍历,若cnt[i]>0,表示这个字符存在,且个数为cnt[i]个
所以要把[l,l+cnt[i]]个位置都要修改为cnt[i]对应的字母,并把l(当前位置后移cnt[i]位)
如果ch=1,对[l,r]升序
做法相同,只是从[0->25]遍历。
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <cstdlib>
#define ls (o<<1)
#define rs (o<<1|1)
#define lson ls,L,M
#define rson rs,M+1,R
using namespace std;
typedef long long ll;
const int N = 100005;
const int sigma = 26;
int sumv[N<<2][sigma], setv[N<<2]; //setv表示当前区间被覆盖的字母
int cnt[26]; //每个坐标在当前区间出现的次数
char str[N];
void pushUp(int o) {
for(int i = 0; i < sigma; i++) {
sumv[o][i] = sumv[ls][i] + sumv[rs][i];
}
}
void initNode(int o) {
memset(sumv[o], 0, sizeof(sumv[o]));
}
void pushDown(int o, int L, int R) {
int M = (L+R)/2;
if(setv[o] != -1) {
setv[ls] = setv[rs] = setv[o];
initNode(ls);
sumv[ls][setv[o]] = (M-L+1);
initNode(rs);
sumv[rs][setv[o]] = (R-M);
setv[o] = -1;
}
}
void build(int o, int L, int R) {
if(L == R) {
initNode(o);
sumv[o][str[L]-'a'] = 1;
setv[o] = str[L]-'a';
return ;
}
setv[o] = -1;
int M = (L+R)/2;
build(lson);
build(rson);
pushUp(o);
}
int query(int o, int L, int R, int ql, int qr, int val) {
if(ql <= L && R <= qr)
return sumv[o][val];
pushDown(o, L, R);
int M = (L+R)/2, ret = 0;
if(ql <= M) ret += query(lson, ql, qr, val);
if(qr > M) ret += query(rson, ql, qr, val);
return ret;
}
void modify(int o, int L, int R, int ql, int qr, int val) {
if(ql <= L && R <= qr) {
for(int i = 0; i < sigma; i++)
sumv[o][i] = 0;
setv[o] = val;
sumv[o][setv[o]] = (R-L+1);
return ;
}
pushDown(o, L, R);
int M = (L+R)/2;
if(ql <= M) modify(lson, ql, qr, val);
if(qr > M) modify(rson, ql, qr, val);
pushUp(o);
}
void getStr(int o, int L, int R) {
if(L == R) {
printf("%c", (char)('a'+setv[o]));
return ;
}
pushDown(o, L, R);
int M = (L+R)/2;
getStr(lson);
getStr(rson);
}
int n, q;
int main() {
while(scanf("%d%d", &n, &q) != EOF) {
scanf("%s", str+1);
build(1, 1, n);
int ql, qr, ch;
while(q--) {
scanf("%d%d%d", &ql, &qr, &ch);
for(int i = 0; i < sigma; i++)
cnt[i] = query(1, 1, n, ql, qr, i);
int pos = ql;
if(ch == 1) {
for(int i = 0; i < sigma; i++) {
if(cnt[i] > 0)
modify(1, 1, n, pos, pos+cnt[i]-1, i);
pos += cnt[i];
}
}else {
for(int i = sigma-1; i >= 0; i--) {
if(cnt[i] > 0)
modify(1, 1, n, pos, pos+cnt[i]-1, i);
pos += cnt[i];
}
}
}
getStr(1, 1, n); puts("");
}
return 0;
}
校赛F 比比谁更快(线段树)的更多相关文章
- hpu校赛--雪人的高度(离散化线段树)
1721: 感恩节KK专场——雪人的高度 时间限制: 1 Sec 内存限制: 128 MB 提交: 81 解决: 35 [提交][状态][讨论版] 题目描述 大雪过后,KK决定在春秋大道的某些区间 ...
- 北邮校赛 F. Gabriel's Pocket Money(树状数组)
F. Gabriel's Pocket Money 2017- BUPT Collegiate Programming Contest - sync 时间限制 2000 ms 内存限制 65536 K ...
- 牛客多校第四场sequence C (线段树+单调栈)
牛客多校第四场sequence C (线段树+单调栈) 传送门:https://ac.nowcoder.com/acm/contest/884/C 题意: 求一个$\max {1 \leq l \le ...
- 校赛F
问题描述 例如对于数列[1 2 3 4 5 6],排序后变为[6 1 5 2 4 3].换句话说,对于一个有序递增的序列a1, a2, a3, ……, an,排序后为an, a1, an-1, a2, ...
- [NOIP10.6模拟赛]2.equation题解--DFS序+线段树
题目链接: 咕 闲扯: 终于在集训中敲出正解(虽然与正解不完全相同),开心QAQ 首先比较巧,这题是\(Ebola\)出的一场模拟赛的一道题的树上强化版,当时还口胡出了那题的题解 然而考场上只得了86 ...
- HDU 4893 Wow! Such Sequence!(2014年多校联合 第三场 G)(线段树)
磨了一天的线段树,不能说完全搞清楚,只能说有一个大概的了解,靠着模板才把这道题A了,只能说太弱~~! 题意: 初始时有一字符串,全为0. 三种操作: 1 k d - add 把d加到第k个数上去2 ...
- 网络赛牡丹江赛区E ZOJ3813(线段树)
http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemId=5345 给定序列P,定义序列S为P反复重复得到的一个无穷长的序列: if P = ...
- Codeforces Round #271 (Div. 2) F. Ant colony (RMQ or 线段树)
题目链接:http://codeforces.com/contest/474/problem/F 题意简而言之就是问你区间l到r之间有多少个数能整除区间内除了这个数的其他的数,然后区间长度减去数的个数 ...
- Codeforces Round #271 (Div. 2) F题 Ant colony(线段树)
题目地址:http://codeforces.com/contest/474/problem/F 由题意可知,最后能够留下来的一定是区间最小gcd. 那就转化成了该区间内与区间最小gcd数相等的个数. ...
随机推荐
- top命令行含义解析
快捷键“1”可以快速切换显示所有cpu的信息 快捷键‘x’可以高亮显示当前排序列 shift+方向键:可以快速切换排序的列 top -c 显示完整命令 load含义解释:http://www.ruan ...
- Android切图注意事项
1.App Logo大小共五种: 48*48 72*72 96*96 144*144 192*192 2. App启动页所需尺寸: 320×480 480×800 720*1280 1080*1920 ...
- mysql手记
myisam innoDB是mysql经常使用的存储引擎 MyISAM不支持事务.也不支持外键.但其訪问速度快.对事务完整性没有要求. InnoDB存储引擎提供了具有提交.回滚和崩溃恢复能力的事务安全 ...
- FZU 2150 Fire Game (暴力BFS)
[题目链接]click here~~ [题目大意]: 两个熊孩子要把一个正方形上的草都给烧掉,他俩同一时候放火烧.烧第一块的时候是不花时间的.每一块着火的都能够在下一秒烧向上下左右四块#代表草地,.代 ...
- <一>读<<大话设计模式>>之简单工厂模式
工厂模式尽管简单.可是写下这篇文章却不简单. 第一:本人经过内心的挣扎后才决定開始写博文的.为什么呢,由于好长时间没有写了,对自己的文学功底也是好不自信.可是技术这东西你不写出来你真不知道自己掌握多少 ...
- Mongodb for PHP教程之数据操作
Mongodb的常用操作 参看手册,php官方的http://us2.php.net/manual/en/mongo.manual.php 也可以参看mongodb官方的教程 数据库连接 ⑴默认格式 ...
- IIS 配置 FTP 网站 H5 音频标签自定义样式修改以及添加播放控制事件
IIS 配置 FTP 网站 在 服务器管理器 的 Web服务器IIS 上安装 FTP 服务 在 IIS管理器 添加FTP网站 配置防火墙规则 说明:服务器环境是Windows Server 200 ...
- ubuntu下spring环境搭建
一.安装JDK 下载官网:http://www.oracle.com/technetwork/java/javase/downloads/jdk8-downloads-2133151.html 部署: ...
- 返回零长度的数组或者集合,而不是null
<<Effective Java>> 第四十三条:返回零长度的数组或者集合,而不是null 假设一个方法的返回值类型是集合或者数组 .假设在方法内部须要返回的集合或者数组是零长 ...
- 程序员的vim
1,所有的Unix like系统都会内建vi文书编辑器,其他的文书编辑器则不一定会存在,但是目前我们使用比较多的是vim编辑器 vim具有程序编辑的能力,可以主动的以字体颜色辨别语法的正确性,方便程序 ...