CF558E-A Simple Task-线段树+计数排序
计数排序的原理,只要知道了有几个数比i小,就可以知道i的位置
这道题只有26个字母,搞26颗线段树,然后区间更新
1 #include <cstdio> 2 #include <cstring> 3 #include <algorithm> 4 5 //using namespace std; 6 const int maxn = 1e5+10; 7 8 int N,Q; 9 char line[maxn]; 10 11 #define lson rt<<1,l,mid 12 #define rson rt<<1|1,mid+1,r 13 #define root 1,1,N 14 15 struct SegrTree{ 16 int num[maxn<<2]; 17 int lazy[maxn<<2]; 18 void init() 19 { 20 memset(lazy,-1,sizeof lazy); 21 } 22 void push_up(int rt) 23 { 24 num[rt] = num[rt<<1] + num[rt<<1|1]; 25 } 26 void push_down(int rt,int m) 27 { 28 if(lazy[rt] != -1) 29 { 30 num[rt<<1] = (m-(m>>1))*lazy[rt] ; 31 num[rt<<1|1] = (m>>1)*lazy[rt] ; 32 lazy[rt<<1] = lazy[rt<<1|1] = lazy[rt]; 33 lazy[rt] = -1; 34 } 35 } 36 void build(int kind,int rt,int l,int r) 37 { 38 if(l == r) 39 { 40 num[rt] = line[l-1]==kind+'a'; 41 //if(line[l-1]=='c') printf("%c pos:%d \n",kind+'a',l); 42 return ; 43 } 44 int mid = (l+r)>>1; 45 build(kind,lson); 46 build(kind,rson); 47 push_up(rt); 48 } 49 void update(int L,int R,int d,int rt,int l,int r) 50 { 51 if(L <= l && R >= r) 52 { 53 num[rt] = (r-l+1)*d; 54 lazy[rt] = d; 55 return ; 56 } 57 push_down(rt,r-l+1); 58 int mid = (l+r)>>1; 59 if(L <= mid) update(L,R,d,lson); 60 if(R > mid) update(L,R,d,rson); 61 push_up(rt); 62 } 63 int query(int L,int R,int rt,int l,int r) 64 { 65 if(L <= l && R >= r) 66 { 67 return num[rt]; 68 } 69 push_down(rt,r-l+1); 70 int mid = (l+r)>>1; 71 int res = 0; 72 73 if(R <= mid) res = query(L,R,lson); 74 else if(L > mid) res = query(L,R,rson); 75 else res = query(L,R,lson)+query(L,R,rson); 76 77 push_up(rt); 78 return res; 79 } 80 }alpha[26]; 81 82 void sort(int l,int r,int k) 83 { 84 int pos,cnt; 85 if(k == 1) 86 { 87 pos = l; 88 for(int i=0;i<26;i++) 89 { 90 cnt = alpha[i].query(l,r,root); 91 //printf("[%d,%d]%c k:%d pos:%d cnt:%d\n",l,r,i+'a',k,pos,cnt); 92 if(cnt) 93 { 94 alpha[i].update(l,r,0,root); 95 alpha[i].update(pos,pos+cnt-1,1,root); 96 pos += cnt; 97 } 98 } 99 } 100 else 101 { 102 pos = l; 103 for(int i=25;i>=0;i--) 104 { 105 cnt = alpha[i].query(l,r,root); 106 //printf("[%d,%d] %c k:%d pos:%d cnt:%d\n",l,r,i+'a',k,pos,cnt); 107 if(cnt) 108 { 109 alpha[i].update(l,r,0,root); 110 alpha[i].update(pos,pos+cnt-1,1,root); 111 pos += cnt; 112 } 113 } 114 } 115 } 116 117 int main() 118 { 119 //freopen("input.txt","r",stdin); 120 121 scanf("%d%d",&N,&Q); 122 scanf("%s",line); 123 124 for(int i=0;i<26;i++) 125 { 126 alpha[i].init(); 127 alpha[i].build(i,root); 128 //printf("tot num:%c %d\n",i+'a',alpha[i].query(1,N,root)); 129 } 130 //printf("c:%d c:%d\n",alpha[2].query(1,N,root),alpha[2].query(7,10,root)); 131 for(int i=0,l,r,k;i<Q;i++) 132 { 133 scanf("%d%d%d",&l,&r,&k); 134 sort(l,r,k); 135 } 136 for(int i=1;i<=N;i++) 137 { 138 for(int j=0;j<26;j++) if(alpha[j].query(i,i,root)) 139 { 140 printf("%c",'a'+j); 141 } 142 } 143 puts(""); 144 }
转载于:https://www.cnblogs.com/helica/p/5752654.html
CF558E-A Simple Task-线段树+计数排序相关推荐
- CF558E A Simple Task 线段树
题解: 这种题之前做过一个类似的题目,也是关于选择区间然后给区间进行排序. 这种题用线段树把排序转换成区间修改区间求和即可. 类似的题目:https://vjudge.net/problem/HDU- ...
- codeforces 558E A Simple Task 线段树
题目链接 题意较为简单. 思路: 由于仅仅有26个字母,所以用26棵线段树维护就好了,比較easy. #include <iostream> #include <string> ...
- 【TJOI2016】【bzoj4552】排序(二分答案+线段树01排序)
problem 给出一个1到n的全排列,现在对这个全排列序列进行m次局部排序 排序分为两种 1:(0,l,r)表示将区间[l,r]的数字升序排序 2:(1,l,r)表示将区间[l,r]的数字降序排序 ...
- gmoj 5405.Permutation(线段树+拓扑排序)
Description 你有一个长度为n 的排列P 与一个正整数K 你可以进行如下操作若干次使得排列的字典序尽量小 对于两个满足|i-j|>=K 且|Pi-Pj| = 1 的下标i 与j,交换P ...
- HDU-3974 Assign the task 线段树 或 直接模拟多叉树 或 并查集 (三种方法)
题目大意 t 组数据(t<=10),每组第一行一个 n 表示 n 个员工(n<=5e4),接下来 n-1 行,每行两个整数 u,v 表示 v 是 u 的上司 然后一行 m 表示有 m 个操 ...
- HDU - 3974 Assign the task (线段树 + dfs序)
HDU - 3974 题意:有个公司有一些关系,每个人(除了boss)都有且仅有一个上司,这就是一棵树的关系,然后会有一些操作,C i,询问第i个人现在的任务,T x y,把y任务给x, 给x相当于给 ...
- 牛客练习赛73 D 离别(线段树+右端点排序离线查询)
牛客练习赛73 D 离别 思路: 对于每一个固定的右端点i,我们都找到一个区间(l,r)使得区间中的点为左端点时 里面最大的的种数为k. 这个可以用队列或者vector来维护. 然后我们对于q个查询, ...
- 【做题记录】区间排序—线段树
1. CF558E A Simple Task 题意: 给定由小写字母组成的字符串 \(s\) 每一次操作如下: \(opt=0\) :将 \([l,r]\) 降序排序 \(opt=1\) :将 \( ...
- 算法与数据结构07:前缀树,计数排序与桶排序
算法与数据结构07:前缀树,计数排序与桶排序 前缀树 计数排序 桶排序 前缀树 Trie 1.根据字符串数组中,每个字符串的字符作为路径,组成而成的一个多叉树结构 2.每个节点都有一个paths数组, ...
最新文章
- 微服务架构下,解决数据一致性问题的实践 2
- matlab 曲线拟合求导,基于matlab曲线拟合的数据预测分析
- 企业软件介绍主页html模板
- 邻接矩阵中啥时候写0和无穷_(一)UDS诊断服务中的诊断会话控制(DiagnosticSessionControl,0x10)...
- 网站暴库原理与方法剖析
- Nginx源码分析 - 主流程篇 - 全局变量cycle初始化(11)
- 硬盘读写性能iozone测试方法及下载
- 百度关键词排名查询源码_推荐4个Google关键词排名查询工具
- 倾斜摄影在高速道路勘测中的应用-案例
- 写一函数fac(n) 求n!。在主函数中输入a,b,c三个整数,实现求a!+b!+c!的值并输出。
- 工程师如何对待开源 | 一个老工程师的肺腑之言
- ios 渐变透明背景_利用PS绘制唯美梦幻多边形背景图
- 平面设计师笔试题应答技巧|智测优聘总结
- 《时空测量原理》韩春好著
- 360视频:CMP和ACP投影
- 【51 Nod 1326】遥远的旅途
- 研究生英文论文练习互改——Peer feedback 和 Peer grading 的访谈思考
- Django 开发MVT-模型
- 圆满收官,在这里读利尔达的2021
- [附源码]java毕业设计企业记账系统