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为降序. 最后输出最终的字符串 首 ...
随机推荐
- python中多线程(1)
一多线程的概念介绍 threading模块介绍 threading模块和multiprocessing模块在使用层面,有很大的相似性. 二.开启多线程的两种方式 1.创建线程的开销比创建进程的开销小, ...
- 【杂文】虚拟键码表(供函数GetAsyncKeyState()使用)
[杂文]虚拟键码表(供函数GetAsyncKeyState()使用) 什么?你说你不知道 \(GetAsyncKeyState()\) ?\(→\)戳我\(←\) (惊奇的发现 \(0\) ~ \(9 ...
- c++ isdigit函数
函数名:isdigit 函数所需头文件:#include<cstdio> 函数格式:isdigit(字符) 函数作用:判断括号内是否为1~9的数字. 例:isdigit(4) 就是true ...
- hdu5924Mr. Frog’s Problem
Mr. Frog's Problem Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/65536 K (Java/Other ...
- zepto中给不存在的元素设置样式并绑定事件的坑
在移动端使用zepto选择器时,一般如果元素不存在会返回一个空的zepto对象. zepto在设置元素样式时,提供了两个入参方式,一种键值对方式$(".ter").css({&qu ...
- DHTML_____window对象属性
<html> <head> <meta charset="utf-8"> <title>window对象属性</title&g ...
- jquery 菜单展开与收缩参考脚本
/* * metismenu - v1.1.3 * Easy menu jQuery plugin for Twitter Bootstrap 3 * https://github.com/onoku ...
- git Eclipse项目不显示当前分支
问题: 在Eclipse中,导入新的git项目,在项目上不再显示当前所处的分支,也不再显示修改了哪些文件 解决: 右键选中项目 --> Team --> Share Project ...
- 自定义 Java Annotation ,读取注解值
1. 首先是自定义注解: package cn.veji.hibernate.po; import java.lang.annotation.ElementType; import java.lang ...
- codeforces_459D_(线段树,离散化,求逆序数)
链接:http://codeforces.com/problemset/problem/459/D D. Pashmak and Parmida's problem time limit per te ...