[CSP-S模拟测试]:string(线段树)
题目描述
给定一个由小写字母组成的字符串$s$。
有$m$次操作,每次操作给定$3$个参数$l,r,x$。
如果$x=1$,将$s[l]~s[r]$升序排序;
如果$x=0$,将$s[l]~s[r]$降序排序。
你需要求出最终序列。
输入格式
第一行两个整数$n,m$。
第二行一个字符串$s$。
接下来m行每行三个整数$l,r,x$。
输出格式
一行一个字符串表示答案。
样例
样例输入
5 2
cabcd
1 3 1
3 5 0
样例输出
abdcc
数据范围与提示
对于$40\%$的数据,$n,m\leqslant 1,000$。
对于$100\%$的数据,$n,m\leqslant 100,000$。
题解
看到这道题,我就想到了:[BZOJ4552]:[Tjoi2016&Heoi2016]排序(桶排序)。
然而,那道题我使用桶排序卡过的,时限还是$6,000ms$,所以我当场懵逼,线段树是肯定看出来了,但是不知道该怎么操作……
打题一定要打正解挖~
$40\%$算法:
直接用$sort$搞就好了,重载一下运算符,我觉得我说的每一句都是废话……
桶排一分也不能多拿(万恶的出题人)。
时间复杂度:
$\Theta(m\times n)$(桶排序)。
$\Theta( m\times n\log n)$(快排)。
期望得分:$40$分。
$100\%$算法:
因为这道题串中只有26个字母,所以就好说多了,用线段树维护区间内$a~z$的个数,每次修改拆成26个修改就行了。
时间复杂度:$\Theta(26\times m\times \log n)$。
期望得分:$100$分。
代码时刻
$40\%$算法:
#include<bits/stdc++.h>
using namespace std;
int n,m,l,r;
bool x;
int a[100001];
char ch[100001];
int t[50];
int st,ed;
void change1()
{
register int maxn=0,minn=20020923,lft=l;
for(int i=l;i<=r;i++)
{
t[a[i]]++;
maxn=max(maxn,a[i]);
minn=min(minn,a[i]);
}
for(register int i=minn;i<=maxn;i++)
while(t[i])
{
a[lft++]=i;
t[i]--;
}
}
void change2()
{
int maxn=0,minn=20020923,lft=l;
for(register int i=l;i<=r;i++)
{
t[a[i]]++;
maxn=max(maxn,a[i]);
minn=min(minn,a[i]);
}
for(register int i=maxn;i>=minn;i--)
while(t[i])
{
a[lft++]=i;
t[i]--;
}
} int main()
{
st=clock();
scanf("%d%d%s",&n,&m,ch+1);
for(register int i=1;i<=n;i++)
a[i]=ch[i]-'a'+1;
while(m--)
{
scanf("%d%d%d",&l,&r,&x);
if(x)change1();
else change2();
}
for(register int i=1;i<=n;i++)
printf("%c",(char)a[i]+'a'-1);
return 0;
}
$100\%$算法:
#include<bits/stdc++.h>
#define L(x) x<<1
#define R(x) x<<1|1
using namespace std;
int n,m;
char ch[100001];
int tr[400001];
int flag[30];
void pushup(int x){if(tr[L(x)]==tr[R(x)])tr[x]=tr[L(x)];}
void pushdown1(int x){if(tr[x])tr[L(x)]=tr[R(x)]=tr[x];}
void pushdown2(int x){if(tr[x])tr[L(x)]=tr[R(x)]=tr[x];tr[x]=0;}
void build(int x,int l,int r)
{
if(l==r){tr[x]=ch[l]-'a'+1;return;}
int mid=(l+r)>>1;
build(L(x),l,mid);
build(R(x),mid+1,r);
pushup(x);
}
void ask(int x,int l,int r,int L,int R)
{
if(r<L||R<l)return;
if(L<=l&&r<=R&&tr[x]){flag[tr[x]]+=r-l+1;return;}
int mid=(l+r)>>1;
pushdown1(x);
ask(L(x),l,mid,L,R);
ask(R(x),mid+1,r,L,R);
}
void change(int x,int l,int r,int L,int R,int v)
{
if(r<L||R<l)return;
if((L<=l&&r<=R)||tr[x]==v){tr[x]=v;return;}
int mid=(l+r)>>1;
pushdown2(x);
change(L(x),l,mid,L,R,v);
change(R(x),mid+1,r,L,R,v);
pushup(x);
}
void print(int x,int l,int r)
{
if(tr[x]){for(int i=l;i<=r;i++)printf("%c",(char)tr[x]+'a'-1);return;}
int mid=(l+r)>>1;
print(L(x),l,mid);
print(R(x),mid+1,r);
}
int main()
{
scanf("%d%d%s",&n,&m,ch+1);
build(1,1,n);
while(m--)
{
int l,r,x;
scanf("%d%d%d",&l,&r,&x);
memset(flag,0,sizeof(flag));
ask(1,1,n,l,r);
if(x)for(int i=1;i<=26;i++){change(1,1,n,l,l+flag[i]-1,i);l+=flag[i];}
else for(int i=26;i>=1;i--){change(1,1,n,l,l+flag[i]-1,i);l+=flag[i];}
}
print(1,1,n);
return 0;
}
rp++
[CSP-S模拟测试]:string(线段树)的更多相关文章
- 【bzoj3638】Cf172 k-Maximum Subsequence Sum 模拟费用流+线段树区间合并
题目描述 给一列数,要求支持操作: 1.修改某个数的值 2.读入l,r,k,询问在[l,r]内选不相交的不超过k个子段,最大的和是多少. 输入 The first line contains inte ...
- 【8.26校内测试】【重构树求直径】【BFS模拟】【线段树维护DP】
题目性质比较显然,相同颜色联通块可以合并成一个点,重新建树后,发现相邻两个点的颜色一定是不一样的. 然后发现,对于一条链来说,每次把一个点反色,实际上使点数少了2个.如下图 而如果一条链上面有分支,也 ...
- [CSP-S模拟测试]:影魔(树状数组+线段树合并)
题目背景 影魔,奈文摩尔,据说有着一个诗人的灵魂.事实上,他吞噬的诗人灵魂早已成千上万.千百年来,他收集了各式各样的灵魂,包括诗人.牧师.帝王.乞丐.奴隶.罪人,当然,还有英雄.每一个灵魂,都有着自己 ...
- 【NOIP模拟】board(线段树维护二进制,树序号化为二进制)
题目背景 SOURCE:NOIP2016-RZZ-2 T3 题目描述 给出这样一棵“二叉树”: 每个节点有左右两个儿子,并如下定义每个节点的高度:假设父亲节点的高度为 h ,那么他的两个儿子的节点的高 ...
- BZOJ2040[2009国家集训队]拯救Protoss的故乡——模拟费用流+线段树+树链剖分
题目描述 在星历2012年,星灵英雄Zeratul预测到他所在的Aiur行星在M天后会发生持续性暴雨灾害,尤其是他们的首都.而Zeratul作为星灵族的英雄,当然是要尽自己最大的努力帮助星灵族渡过这场 ...
- 2018.10.20 NOIP模拟 蛋糕(线段树+贪心/lis)
传送门 听说是最长反链衍生出的对偶定理就能秒了. 本蒟蒻直接用线段树模拟维护的. 对于第一维排序. 维护第二维的偏序关系可以借助线段树/树状数组维护逆序对的思想建立权值线段树贪心求解. 代码
- 2018.06.29 NOIP模拟 旅馆(线段树)
旅馆 [问题描述] OIEROIEROIER 们最近的旅游计划,是到长春净月潭,享受那里的湖光山色,以及明 媚的阳光.你作为整个旅游的策划者和负责人,选择在潭边的一家著名的旅馆住 宿.这个巨大的旅馆一 ...
- 2018.06.29 NOIP模拟 排列(线段树)
排列(premu.cpp) [题目描述] 对于一个 1 到 n 的排列,逆序数的定义为:排列中第 i 位 ai的逆序数就是 a1-ai-1中比 ai大的数的个数.另外用 pi表示 a1,-,ai的逆序 ...
- 考试题string——线段树。
string[题目描述]给定一个由小写字母组成的字符串 s.有 m 次操作,每次操作给定 3 个参数 l,r,x.如果 x=1,将 s[l]~s[r]升序排序;如果 x=0,将 s[l]~s[r]降序 ...
随机推荐
- 多线程14-Barrier
, b => Console.WriteLine()); ; i <= ; i++) { Console.Write ...
- The order of a Tree
The order of a Tree Problem Description As we know,the shape of a binary search tree is greatly rela ...
- lb开金矿 QDUOJ 数论
lb开金矿 QDUOJ 数论 原题链接,点我进去 题意 大家都知道lb有n个小弟(编号从2到n+1),他们可以按照规则传递信息:某天编号为i的小弟收到信息后,那么第二天他会给编号为j的小弟传达信息,其 ...
- Centos7防火墙开启3306端口
CentOS7的默认防火墙为firewall,且默认是不打开的. systemctl start firewalld # 启动friewall systemctl status firewalld # ...
- python递归方式和普通方式实现输出和查询斐波那契数列
●斐波那契数列 斐波那契数列(Fibonacci sequence),是从1,1开始,后面每一项等于前面两项之和. 如果为了方便可以用递归实现,要是为了性能更好就用循环. ◆递归方式实现生成前30个斐 ...
- Distributed Deep Learning
安利一下刘铁岩老师的<分布式机器学习>这本书 以及一个大神的blog: https://zhuanlan.zhihu.com/p/29032307 https://zhuanlan.zhi ...
- gomock
参考 使用Golang的官方mock工具--gomock
- spring boot 枚举使用的坑2
上一篇说到在枚举当在controller的方法做参数时的坑,解决方法是配置了一个converter,后来想想,如果不闲每次都加一个注解麻烦的话,可以在参数前面加一个注解,添加一个解析器应该也可以解决这 ...
- 华为云搭建windows+wordpress+xampp
1.如何将本地文件上传至华为云ECS云服务器(Windows系统) 1.1 在本地电脑上,快捷键“WIN+R"打开“运行”中输入“mstsc”,点击确定 1.2 在“远程桌面连接”框点击“ ...
- 一般软件开发流程和BBS表设计
项目开发流程 需求分析 架构师+产品经理+开发组组长 和客户公司谈需求之前 ,事先需要想一下这个项目要怎么做 里面的坑点提前想好比较简单的解决方案 在跟客户谈的时候有意识的引导客户朝你已经想好的方案上 ...