CF558E A simple task 线段树
这道题好猥琐啊啊啊啊啊啊
写了一个上午啊啊啊啊
没有在update里写pushup啊啊啊啊
题目大意:
给你一个字符串s,有q个操作
l r 1 :把sl..rsl..r按升序排序
l r 0 :把sl..rsl..r按降序排序
Solution:
我们考虑建26棵线段树,第i棵线段树的[x,y]表示在[x,y]中一共有多少个字母'a'+i-1
至于修改时我们可以以升序为例,从a至z按顺序往前丢,记得要清空区间
同理,降序反过来就是了
Code:
我们可以用sort啊啊,只不过会TLE
#pragma GCC optimize(3)
#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
int n,q;
char s[100001];
bool cmp(char a,char b){
return a>b;
}
int main(){
scanf("%d%d%s",&n,&q,s);
for(int i=1;i<=q;i++){
int l,r,x;
scanf("%d%d%d",&l,&r,&x);
if(x==1)sort(s+l-1,s+r);
else sort(s+l-1,s+r,cmp);
printf("%s\n",s);
}
printf("\n%s",s);
return 0;
}
这里才是正解代码
#include<iostream>
#include<cstdio>
#include<cstring>
using namespace std;
char s[1000001];
int n,m,sum[27][400001],lazy[27][400001];
inline int rd(){
register int x=0,y=1;
register char c=getchar();
while(c>'9' or c<'0'){
if(c=='-'){
y=-1;
}
c=getchar();
}
while(c>='0' and c<='9'){
x=(x<<1)+(x<<3)+(c^48);
c=getchar();
}
return x*y;
}
inline void pushup(int o,int rt){
sum[rt][o]=sum[rt][o<<1]+sum[rt][o<<1|1];
}
inline void pushdown(int o,int l,int r,int rt){
if(lazy[rt][o]!=-1){
int mid=(l+r)>>1;
sum[rt][o]=lazy[rt][o]*(r-l+1);
sum[rt][o<<1]=lazy[rt][o]*(mid-l+1);
sum[rt][o<<1|1]=lazy[rt][o]*(r-mid);
lazy[rt][o<<1]=lazy[rt][o<<1|1]=lazy[rt][o];
lazy[rt][o]=-1;
}
}
void build(int o,int l,int r){
if(l==r){
sum[s[l]-'a'+1][o]=1;
return;
}
int mid=(l+r)>>1;
build(o<<1,l,mid);
build(o<<1|1,mid+1,r);
for(int i=1;i<=26;i++)pushup(o,i);
}
inline int query(int o,int l,int r,int x,int y,int rt){
if(x<=l and y>=r){
return sum[rt][o];
}
pushdown(o,l,r,rt);
int mid=(l+r)>>1,ret=0;
if(x<=mid)ret+=query(o<<1,l,mid,x,y,rt);
if(y>mid)ret+=query(o<<1|1,mid+1,r,x,y,rt);
return ret;
}
inline void update(int o,int l,int r,int x,int y,int rt,int v){
if(x<=l and y>=r){
lazy[rt][o]=v;
sum[rt][o]=v*(r-l+1);
return;
}
pushdown(o,l,r,rt);
int mid=(l+r)>>1;
if(x<=mid)update(o<<1,l,mid,x,y,rt,v);
if(y>mid)update(o<<1|1,mid+1,r,x,y,rt,v);
pushup(o,rt);
}
void output(int o,int l,int r){
if(l==r){
for(int i=1;i<=26;i++){
if(sum[i][o]){
s[l]='a'+i-1;
break;
}
}
return;
}
for(int i=1;i<=26;i++)pushdown(o,l,r,i);
int mid=(l+r)>>1;
output(o<<1,l,mid);
output(o<<1|1,mid+1,r);
}
int main(){
for(int i=1;i<=26;i++)memset(lazy[i],-1,sizeof(lazy[i]));
n=rd(),m=rd();
scanf("%s",s+1);
build(1,1,n);
while(m--){
int x=rd(),y=rd();
if(rd()){
int tmp=x-1;
for(int i=1;i<=26;i++){
int cas=query(1,1,n,x,y,i);
if(!cas)continue;
update(1,1,n,x,y,i,0);
update(1,1,n,tmp+1,tmp+cas,i,1);tmp=tmp+cas;
}
}else {
int tmp=x-1;
for(int i=26;i>=1;i--){
int cas=query(1,1,n,x,y,i);
if(!cas)continue;
update(1,1,n,x,y,i,0);
update(1,1,n,tmp+1,tmp+cas,i,1);tmp=tmp+cas;
}
}
}
output(1,1,n);
printf("%s\n",s+1);
return 0;
}
CF558E A simple task 线段树的更多相关文章
- Codeforces Round #312 (Div. 2) E. A Simple Task 线段树
E. A Simple Task 题目连接: http://www.codeforces.com/contest/558/problem/E Description This task is very ...
- Codeforces Round #312 (Div. 2) E. A Simple Task 线段树+计数排序
题目链接: http://codeforces.com/problemset/problem/558/E E. A Simple Task time limit per test5 secondsme ...
- CodeForces 588E A Simple Task(线段树)
This task is very simple. Given a string S of length n and q queries each query is on the format i j ...
- Codeforces Round #312 (Div. 2) E. A Simple Task 线段树 延时标记
E. A Simple Task time limit per test5 seconds memory limit per test512 megabytes inputstandard input ...
- Codeforces 588E. A Simple Task (线段树+计数排序思想)
题目链接:http://codeforces.com/contest/558/problem/E 题意:有一串字符串,有两个操作:1操作是将l到r的字符串升序排序,0操作是降序排序. 题解:建立26棵 ...
- CF #312 E. A Simple Task 线段树
题目链接:http://codeforces.com/problemset/problem/558/E 给一个字符串,每次对一个区间内的子串进行升序或者降序的排列,问最后字符串什么样子. 对于字符串排 ...
- codeforces 558E A Simple Task 线段树
题目链接 题意较为简单. 思路: 由于仅仅有26个字母,所以用26棵线段树维护就好了,比較easy. #include <iostream> #include <string> ...
- [Codeforces558E]A Simple Task 线段树
链接 题意:给定一个长度不超过 \(10^5\) 的字符串(小写英文字母),和不超过5000个操作. 每个操作 L R K 表示给区间[L,R]的字符串排序,K=1为升序,K=0为降序. 最后输出最终 ...
- CF558E A Simple Task
题目大意: 给定一个长度不超过10^5的字符串(小写英文字母),和不超过5000个操作. 每个操作 L R K 表示给区间[L,R]的字符串排序,K=1为升序,K=0为降序. 最后输出最终的字符串 首 ...
随机推荐
- C# 访问mongodb数据库
1.引用四个mongodb动态库MongoDB.Bson.dll,MongoDB.Driver.Core.dll,MongoDB.Driver.dll,MongoDB.Driver.Legacy.dl ...
- LN : leetcode 242 Valid Anagram
lc 242 Valid Anagram 242 Valid Anagram Given two strings s and t, write a function to determine if t ...
- opencv识别验证码的教程和资料
简书教程:https://www.jianshu.com/p/41127bf90ca9 博客园教程(较详细):https://www.cnblogs.com/qqandfqr/p/7866650.ht ...
- 2014中秋节,用java为QQ游戏美女找茬写辅助
引子 今年中秋闲在家,总要找点事做. 前几天开始学python,很早之前就有计划拿下这门语言了,可惜一直拖到现在……不可否认,我也是个拖沓症患者.在学习python的过程中 ...
- 字符编码方式ASCII、Unicode、UTF-8
一.ASCII 1.介绍 即American Standard Code for Information Interchange(美国信息交换标准代码),是基于拉丁字母的,主要用于显示现代英语和其他西 ...
- Mac上简单常用Terminal命令
方案1 SSH是一个非常伟大的工具,如果你要在互联网上远程连接到服务器,那么SSH无疑是最佳的候选.SSH是加密的,OpenSSH加密所有通信(包括密码),有效消除了窃听,连接劫持和其它攻击.本文将为 ...
- 如何安装Ant,配置环境变量??
Apache Ant,是一个将软件编译.测试.部署等步骤联系在一起加以自动化的一个工具,大多用于Java环境中的软件开发. Ant是一个基于Java,并且主要用于Java工程的构建工具.Ant本意是A ...
- c++写入txt
用ofstream 输出流,#include <fstream> ofstream outf; outf.open("abc.txt");outf<<123 ...
- 08Java Server Pages 语法
Java Server Pages 语法 基础语法 注释 <!-- -->可以在客户端通过源代码看到:<%-- --%>在客户端通过查看源代码看不到. <!--浏 ...
- flipt 一个基于golang 的特性工具开发类库
以前介绍过一个Flagr 的基于golang 的特性功能开发类库(技术雷达推荐),今天看到一个类似也很不错的方案flipt 参考架构 包含的特性 快速,使用golang 编写,同时进行了性能优化 运行 ...