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为降序. 最后输出最终的字符串 首 ...
随机推荐
- js 获取图片宽高 和 图片大小
获取要查看大小的img var img_url = 'http://img5.imgtn.bdimg.com/it/u=4267222417,1017407570&fm=200&gp= ...
- 51nod 1018 排序
1018 排序 基准时间限制:1 秒 空间限制:131072 KB 分值: 0 难度:基础题 收藏 关注 给出N个整数,对着N个整数进行排序 Input 第1行:整数的数量N(1 <= N ...
- CSS之选择符、链接、盒子模型、显示隐藏元素
<html> <head> <meta charset="utf-8"> <title>选择符.链接.盒子模型.显示隐藏元素< ...
- JavaScript 正则表达式(转自 mozilla)
正则表达式是被用来匹配字符串中的字符组合的模式.在JavaScript中,正则表达式也是对象. 这种模式可以被用于 RegExp 的 exec 和 test 方法以及 String 的 match.r ...
- 石墨烯(转自wiki)
石墨烯(Graphene)是一种由碳原子以sp2杂化轨道组成六角型呈蜂巢晶格的平面薄膜,只有一个碳原子厚度的二维材料[1].石墨烯一直被认为是假设性的结构,无法单独稳定存在[1],直至2004年,英国 ...
- 300 Longest Increasing Subsequence 最长上升子序列
给出一个无序的整形数组,找到最长上升子序列的长度.例如,给出 [10, 9, 2, 5, 3, 7, 101, 18],最长的上升子序列是 [2, 3, 7, 101],因此它的长度是4.因为可能会有 ...
- SQL 几个查看性能的语句
1.查找目前SQL Server所执行的SQL语法,并展示资源情况: SELECT s2.dbid , DB_NAME(s2.dbid) AS [数据库名] , --s1.sql_handle , ( ...
- Jmeter各组件介绍 及 使用
本篇主要讲述Jmeter的各个组件及简单使用,其中包括以下内容: 一.线程组二.逻辑控制器三.配置元件四.定时器五.后置处理器六.断言七.监听器 八.参数化 网上大神整理的链接:http://blog ...
- 用rownum先排序后分页
今天突然想到rownum可以解决分页问题,于是做了各种实验,找个几个文章,最后有了一定成果. 现有表tablename,含有字段showorder,要求提取showorder的第11行到20行数据. ...
- [AC自动机模板]Keywords Search
只是记录一下代码 AC自动机算法的教程请移步这里 还有这里 指针看着懵逼的还可以看一下这里 #include<iostream> #include<cstdio> #inclu ...