cf#312-E-A Simple Task- 线段树+暴力(计数排序)
2016-04-07 15:47
435 查看
http://codeforces.com/contest/558/problem/E
题意:给定一个字符串,有q次操作,每次操作将(l,r)内的字符升序或降序排列,输出q次操作后的字符串。
是这题的加强版:http://blog.csdn.net/viphong/article/details/50803134,这题L全是1,本题的l是任意的
如果L是1直接贪心就好。
本题有个地方简化了的就是字符集 只有26个字母。
于是每次操作我们可以暴力模拟,
【开26个线段树,第K个线段树的下标i 对应 第i个位置是否有字母K】
于是每次操作【x,y】:
26个线段树查询出【x,y】的字母a,bc,d,...z的个数,存到数组tmp[26]
如果是升序,遍历数组tmp,如果tmp[ 'a' ]!=0,则把 a字母对应线段树的【x,x+tmp['a']-1】更新为1,当然【x,y】内的其余地方更新为0即可
降序同理
最后只需要查询每个位置i,在哪个线段树上,就说明位置i要填哪个字母
复杂度是26*n*lgn
跑得略慢咯。。 2355ms
题意:给定一个字符串,有q次操作,每次操作将(l,r)内的字符升序或降序排列,输出q次操作后的字符串。
是这题的加强版:http://blog.csdn.net/viphong/article/details/50803134,这题L全是1,本题的l是任意的
如果L是1直接贪心就好。
本题有个地方简化了的就是字符集 只有26个字母。
于是每次操作我们可以暴力模拟,
【开26个线段树,第K个线段树的下标i 对应 第i个位置是否有字母K】
于是每次操作【x,y】:
26个线段树查询出【x,y】的字母a,bc,d,...z的个数,存到数组tmp[26]
如果是升序,遍历数组tmp,如果tmp[ 'a' ]!=0,则把 a字母对应线段树的【x,x+tmp['a']-1】更新为1,当然【x,y】内的其余地方更新为0即可
降序同理
最后只需要查询每个位置i,在哪个线段树上,就说明位置i要填哪个字母
复杂度是26*n*lgn
跑得略慢咯。。 2355ms
#include <cstdio> #include <cmath> #include <cstring> #include <string> #include <algorithm> #include <queue> #include <map> #include <vector> #include <iostream> using namespace std; const double pi=acos(-1.0); double eps=0.000001; int min(int a,int b) {return a<b?a:b;} int max(int a,int b) {return a>b?a:b;} const int N=100005; struct tree { int sum[4*N]; int set[4*N]; void pushdown(int i,int l,int r) { if (set[i]!=-1) { int mid=(l+r)>>1; set[i<<1]=set[i]; set[i<<1|1]=set[i]; sum[i<<1]=set[i]*(mid-l+1); sum[i<<1|1]=set[i]*(r-mid); set[i]=-1; } } void update(int i,int l,int r,int ql,int qr,int val) { if (ql>qr) return ; //防止越界啦。 if (r<ql||l>qr) return ; if (l>=ql&&r<=qr) { sum[i]=(r-l+1)*val; set[i]=val; return ; } pushdown(i,l,r); int mid=(l+r)>>1; update(i<<1,l,mid,ql,qr,val); update(i<<1|1,mid+1,r,ql,qr,val); sum[i]=sum[i<<1]+sum[i<<1|1]; } int query(int i,int l,int r,int ql,int qr) { if (l>qr||r<ql) return 0; if (l>=ql&&r<=qr) return sum[i]; pushdown(i,l,r); int mid=(l+r)>>1; return query(i<<1,l,mid,ql,qr) +query(i<<1|1,mid+1,r,ql,qr); } void init() { memset(set,-1,sizeof set); } }; tree tp[26]; char s[100005]; int tmp[30]; int main() { int n,q; int x,y,z,i,j; cin>>n>>q; scanf("%s",s+1); for (i=0;i<26;i++) tp[i].init(); for(i=1;i<=n;i++) //init tp[s[i]-'a'].update(1,1,n,i,i,1); for (i=1;i<=q;i++) { scanf("%d%d%d",&x,&y,&z); for (j=0;j<26;j++) //counting tmp[j]=tp[j].query(1,1,n,x,y); if (z==1) { int start_pos=x; for (j=0;j<26;j++) //sorting { if (!tmp[j])continue; tp[j].update(1,1,n,x,start_pos-1,0); tp[j].update(1,1,n,start_pos,start_pos+tmp[j]-1,1); //把字母填到该区间,其余位置置零 tp[j].update(1,1,n,start_pos+tmp[j],y,0); start_pos+=tmp[j]; //更新start_pos } } else //逆序 { int start_pos=x; for (j=25;j>=0;j--) { if (!tmp[j])continue; tp[j].update(1,1,n,x,start_pos-1,0); tp[j].update(1,1,n,start_pos,start_pos+tmp[j]-1,1); tp[j].update(1,1,n,start_pos+tmp[j],y,0); start_pos+=tmp[j]; } } } for (i=1;i<=n;i++) { for (j=0;j<26;j++) if (tp[j].query(1,1,n,i,i)) break; s[i]=j+'a'; } printf("%s\n",s+1); return 0; }
相关文章推荐
- 升级JDK版本后,SpringServletContainerInitializer cannot be cast to javax.servlet.ServletContainerInitializ
- Android手机在开发调试时logcat不显示输出信息的解决办法
- iOS项目中安装和使用 Cocoapods
- 网络原理,以及对VMware Workstation虚拟网络VMnet0、VMnet1、VMnet8的图解
- Windows下react-native安装步骤以及安装时候遇到各类已填平的坑
- NSTimer扩展block版(用block写定时器)
- 7.2 LOCAL_STATE:virtual模块核心结构体
- hosts文件地址
- 面试题49 把字符串转换成整数
- Beat---hdu2614
- DBText除了左右左对齐且上下Base对齐的其对齐点为Position外,其余的都是AlignmentPoint
- 2016年上半年系统集成中项4月6日作业
- zabbix中文乱码解决方法
- TCP server 为什么一个端口可以建立多个连接?(网络讨论)
- uart stdio的移植3
- C++设计模式<二>:面向对象设计原则
- 保留两位小数
- MySQL修改root密码的多种方法
- BZOJ 2728: [HNOI2012]与非
- easyui的datagrid的分页问题