[Codeforces Round#312 Div.2] A Simple Task 【线段树+lazy_tag】
2015-08-09 00:19
393 查看
[Codeforces Round#312 Div.2] A Simple Task
题目描述
给出一个长度为n的字符串,给出q个区间,要求依次将区间内的字符按非升/非降进行排序,输出最后的字符串。数据范围
1≤n≤105,0≤q≤500001 ≤ n ≤ 10^{5} , 0 ≤ q ≤ 50000样例输入
10 5abacdabcda
7 10 0
5 8 1
1 4 0
3 6 0
7 10 1
样例输出
cbcaaaabdd其实一开始我是不愿意写26个线段树的。。。
我固执地使用自己的单个线段树版,每次区间都需要从11循环到2626当前区间的cnt[i]cnt[i]这个直接导致了我做此题用了半天!!8个小时!!从test9 TLE 升级到test22 TLE 最后升级到test53 TLE再也切不动了。。。
正题:
用26个线段树维护每个区间该字符的个数,(从小到大/从大到小)更替这个区间的字符串,所以就不用sort排序了,需要用lazy懒标记,2000+ms过。【该用空间的地方就用0 0】对了,还有一个不起眼的小优化,也不知道它为我最后的AC贡献了多少时间。。。就是如果操作中出现两个区间前者被后者框在了里面,就可以删去前者,我用了手写栈。。。
码:
[code]#include<iostream> #include<cstring> #include<cstdio> #include<string> #define LCH(i) (2 * i) #define RCH(i) (2 * i + 1) const int maxn = 1e5; const int maxl = 26; const int maxo = 50000; using namespace std; struct OP { int l, r, ope; }op[maxo + 5], sta[maxo + 5]; struct T { int lc, rc, cnt; int size(){ if(lazy == 1)return rc - lc + 1; else return 0; } int lazy; }tree[maxl + 5][maxn * 4]; int n, q, top, tmp[maxl + 5]; char str[maxn + 5]; void del() { for(int i = 1; i <= q; i ++){ while(top > 0 && sta[top].l >= op[i].l && sta[top].r <= op[i].r) -- top; sta[++ top] = op[i]; } for(int i = 1; i <= top; i ++) op[i] = sta[i]; q = top; } void built(int i, int l, int r, int alpha) { tree[alpha][i].lc = l, tree[alpha][i].rc = r; if(l == r){ if(str[l] - 'a' == alpha)tree[alpha][i].cnt ++; return ; } int mid = (l + r) / 2; built(LCH(i), l, mid, alpha); built(RCH(i), mid + 1, r, alpha); tree[alpha][i].cnt = tree[alpha][LCH(i)].cnt + tree[alpha][RCH(i)].cnt; return; } void query(int i, int l, int r, int alpha){ if(tree[alpha][i].rc < l || tree[alpha][i].lc > r)return ; if(tree[alpha][i].lc >= l && tree[alpha][i].rc <= r){ tmp[alpha] += tree[alpha][i].cnt; tree[alpha][i].lazy = 1; return; } else { if(tree[alpha][i].lazy){ tree[alpha][LCH(i)].lazy = tree[alpha][i].lazy; tree[alpha][RCH(i)].lazy = tree[alpha][i].lazy; tree[alpha][LCH(i)].cnt = tree[alpha][LCH(i)].size(); tree[alpha][RCH(i)].cnt = tree[alpha][RCH(i)].size(); tree[alpha][i].lazy = 0; } query(LCH(i), l, r, alpha); query(RCH(i), l, r, alpha); } } void update(int i, int l, int r, int alpha, int val) { if(tree[alpha][i].lc > r || tree[alpha][i].rc < l)return; if(tree[alpha][i].lc >= l && tree[alpha][i].rc <= r){ tree[alpha][i].lazy = val; tree[alpha][i].cnt = tree[alpha][i].size(); return; } else { if(tree[alpha][i].lazy){ tree[alpha][LCH(i)].lazy = tree[alpha][i].lazy; tree[alpha][RCH(i)].lazy = tree[alpha][i].lazy; tree[alpha][LCH(i)].cnt = tree[alpha][LCH(i)].size(); tree[alpha][RCH(i)].cnt = tree[alpha][RCH(i)].size(); tree[alpha][i].lazy = 0; } update(LCH(i), l, r, alpha, val); update(RCH(i), l, r, alpha, val); tree[alpha][i].cnt = tree[alpha][LCH(i)].cnt + tree[alpha][RCH(i)].cnt; return; } } int main() { scanf("%d %d\n", &n, &q); gets(str + 1); for(int i = 1; i <= q; i ++) scanf("%d%d%d", &op[i].l, &op[i].r, &op[i].ope); del();//小优化 for(int i = 0; i < maxl; i ++) built(1, 1, n, i); int xlen; for(int i = 1; i <= q; i ++){ for(int j = 0; j < maxl; j ++){ query(1, op[i].l, op[i].r, j); update(1, op[i].l, op[i].r, j, 2); } xlen = op[i].l; if(op[i].ope){ for(int j = 0; j < maxl; j ++){ if(!tmp[j])continue; update(1, xlen, xlen + tmp[j] - 1, j, 1); while(tmp[j]){//更新当前字符串 str[xlen ++] = j + 'a'; tmp[j] --; } } } else{ for(int j = maxl - 1; j >= 0; j --){ if(!tmp[j])continue; update(1, xlen, xlen + tmp[j] - 1, j, 1); while(tmp[j]){//更新当前字符串 str[xlen ++] = j + 'a'; tmp[j] --; } } } //printf("%s", str + 1); //puts(""); } printf("%s", str + 1); }
相关文章推荐
- 模式分类 绪论
- hdu 5365 Run(BC 50 B题)(求四边形的个数)
- 黑马程序员--java基础--网络编程
- HDU 5365 Run ——BestCoder Round #50(div.1 div.2)
- CCS5.1/5.5/6下载地址
- Python-Selenium2做Web自动化测试(3)-环境搭建以及第一个脚本
- POJ - 3352 Road Construction(边双连通分量)
- 学习笔记——maven的操作和使用
- HDU1241 Oil Deposits
- Brew:command not found in Macbook
- Longest Palindromic Substring
- Bash中的数学计算
- 操作系统概述
- tcpreplay工具安装使用
- java并发 非阻塞同步算法与CAS(Compare and Swap)无锁算法
- 机器学习中的算法(1)-决策树模型组合之随机森林与GBDT
- net.sf.ehcache.config.Configurator#configure : No configuration found.
- HDU 5366 The mook jong(DP)
- SVN如何避免冲突
- ViewFlipper实现ViewPager的页面切换效果