计数排序的原理,只要知道了有几个数比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-线段树+计数排序相关推荐

  1. CF558E A Simple Task 线段树

    题解: 这种题之前做过一个类似的题目,也是关于选择区间然后给区间进行排序. 这种题用线段树把排序转换成区间修改区间求和即可. 类似的题目:https://vjudge.net/problem/HDU- ...

  2. codeforces 558E A Simple Task 线段树

    题目链接 题意较为简单. 思路: 由于仅仅有26个字母,所以用26棵线段树维护就好了,比較easy. #include <iostream> #include <string> ...

  3. 【TJOI2016】【bzoj4552】排序(二分答案+线段树01排序)

    problem 给出一个1到n的全排列,现在对这个全排列序列进行m次局部排序 排序分为两种 1:(0,l,r)表示将区间[l,r]的数字升序排序 2:(1,l,r)表示将区间[l,r]的数字降序排序 ...

  4. gmoj 5405.Permutation(线段树+拓扑排序)

    Description 你有一个长度为n 的排列P 与一个正整数K 你可以进行如下操作若干次使得排列的字典序尽量小 对于两个满足|i-j|>=K 且|Pi-Pj| = 1 的下标i 与j,交换P ...

  5. HDU-3974 Assign the task 线段树 或 直接模拟多叉树 或 并查集 (三种方法)

    题目大意 t 组数据(t<=10),每组第一行一个 n 表示 n 个员工(n<=5e4),接下来 n-1 行,每行两个整数 u,v 表示 v 是 u 的上司 然后一行 m 表示有 m 个操 ...

  6. HDU - 3974 Assign the task (线段树 + dfs序)

    HDU - 3974 题意:有个公司有一些关系,每个人(除了boss)都有且仅有一个上司,这就是一棵树的关系,然后会有一些操作,C i,询问第i个人现在的任务,T x y,把y任务给x, 给x相当于给 ...

  7. 牛客练习赛73 D 离别(线段树+右端点排序离线查询)

    牛客练习赛73 D 离别 思路: 对于每一个固定的右端点i,我们都找到一个区间(l,r)使得区间中的点为左端点时 里面最大的的种数为k. 这个可以用队列或者vector来维护. 然后我们对于q个查询, ...

  8. 【做题记录】区间排序—线段树

    1. CF558E A Simple Task 题意: 给定由小写字母组成的字符串 \(s\) 每一次操作如下: \(opt=0\) :将 \([l,r]\) 降序排序 \(opt=1\) :将 \( ...

  9. 算法与数据结构07:前缀树,计数排序与桶排序

    算法与数据结构07:前缀树,计数排序与桶排序 前缀树 计数排序 桶排序 前缀树 Trie 1.根据字符串数组中,每个字符串的字符作为路径,组成而成的一个多叉树结构 2.每个节点都有一个paths数组, ...

最新文章

  1. 微服务架构下,解决数据一致性问题的实践 2
  2. matlab 曲线拟合求导,基于matlab曲线拟合的数据预测分析
  3. 企业软件介绍主页html模板
  4. 邻接矩阵中啥时候写0和无穷_(一)UDS诊断服务中的诊断会话控制(DiagnosticSessionControl,0x10)...
  5. 网站暴库原理与方法剖析
  6. Nginx源码分析 - 主流程篇 - 全局变量cycle初始化(11)
  7. 硬盘读写性能iozone测试方法及下载
  8. 百度关键词排名查询源码_推荐4个Google关键词排名查询工具
  9. 倾斜摄影在高速道路勘测中的应用-案例
  10. 写一函数fac(n) 求n!。在主函数中输入a,b,c三个整数,实现求a!+b!+c!的值并输出。
  11. 工程师如何对待开源 | 一个老工程师的肺腑之言
  12. ios 渐变透明背景_利用PS绘制唯美梦幻多边形背景图
  13. 平面设计师笔试题应答技巧|智测优聘总结
  14. 《时空测量原理》韩春好著
  15. 360视频:CMP和ACP投影
  16. 【51 Nod 1326】遥远的旅途
  17. 研究生英文论文练习互改——Peer feedback 和 Peer grading 的访谈思考
  18. Django 开发MVT-模型
  19. 圆满收官,在这里读利尔达的2021
  20. [附源码]java毕业设计企业记账系统

热门文章

  1. 编程语言对比 导入模块
  2. neo4j 增 create
  3. echarts scatter
  4. Maven学习总结(49)——Maven Profile详解
  5. eslint 设置目录_Nuxt项目添加自定义ESLint规则
  6. ca 自建 颁发证书_自建 ca 及使用 ca 颁发证书
  7. python records库_Python Records库使用举例
  8. spring 集成 spring cloud config 的相关知识
  9. jsencrypt代码分析——openssl的rsa加密解密在js的实现
  10. 6个好用的Web开发工具