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为降序. 最后输出最终的字符串 首 ...
随机推荐
- 测试神器Swagger的相关使用
1.Swagger简介 swagger官网地址: https://swagger.io/ swagger官网文档介绍地址: https://swagger.io/about/ swagge是一个易 ...
- 洛谷 P1064 金明的预算方案(有依赖的背包问题)
题目描述 金明今天很开心,家里购置的新房就要领钥匙了,新房里有一间金明自己专用的很宽敞的房间.更让他高兴的是,妈妈昨天对他说:“你的房间需要购买哪些物品,怎么布置,你说了算,只要不超过N元钱就行”.今 ...
- 如何保证access_token长期有效--微信公众平台开发
http://blog.csdn.net/qq_33556185/article/details/52758781 import javax.servlet.ServletContext; impor ...
- Apache Kafka官方文档翻译(原创)
Apache Kafka是一个分布式流平台.准确的说是什么意思呢?我们认为流平台具有三种关键能力: 1.让你对数据流进行发布订阅.因此他很像一个消息队列和企业级消息系统. 2.让你以高容错的方式存储数 ...
- [译]curl_multi_perform
http://curl.haxx.se/libcurl/c/curl_multi_perform.html curl_multi_perform.3 -- man page NAMEcurl_mult ...
- centos 7 中防火墙的关闭问题
新安装的centos 7 发现有些程序端口是关闭的,想到了防火墙和selinux selinx 好关闭 /etc/sysconfig/selinux 中 追加 SELINUX=disabled 防火 ...
- jQuery学习笔记(2)-选择器的使用
一.选择器是什么 有了jQuery的选择器,我们几乎可以获取页面上任意一个或一组对象 二.Dom对象和jQuery包装集 1.Dom对象 JavaScript中获取Dom对象的方式 <div i ...
- (二)Mybatis总结之通过Dao层与数据交互
Mybatis概述 定义: Mybatis是一个支持普通sql查询,存储过程和高级映射的优秀持久层框架. Mybatis是(半自动的)跟数据库打交道的orm(object relationship m ...
- java excel poi导入 过滤空行的方法 判断是否是空行
private boolean isRowEmpty(Row row){ for (int c = row.getFirstCellNum(); c < row.getLastCellNum() ...
- Android Studio 1.5启动出现“SDK Manager: failed to install”问题的解决
问题描述 Android Studio 1.5是当前最新Android手机应用开发平台,下载bundle版安装后,启动Studio后出现“SDK Manager: failed to install” ...