给出长度为n的字符串,m个操作。

每一个操作有三个值 l,r,op。

op==1,表示将字符串中[ l ,r ]的部分依照升序排列。

op==0,表示将字符串中[ l ,r ]的部分依照降序排列。

输出终于的字符串

按小写字母建26颗线段树

对于每次改动,先记录[l,r]区间内各个字母出现的次数,并对对应区间清空,然后依照升序或者降序从新更新

#include "stdio.h"
#include "string.h" char str[100010];
int n,temp;
struct node
{
int l,r,x,lazy;
}data[30][400010];
void build(int l,int r,int k,int op)
{
int mid;
data[op][k].l=l;
data[op][k].r=r;
data[op][k].x=0;
data[op][k].lazy=-1;
if (l==r)
return ; mid=(l+r)/2;
build(l,mid,k*2,op);
build(mid+1,r,k*2+1,op);
} void Pushdown(int k,int op)
{
if (data[op][k].lazy==-1) return ;
if (data[op][k].l==data[op][k].r) return ; if (data[op][k].lazy==0)
{
data[op][k*2].x=data[op][k*2].lazy=0;
data[op][k*2+1].x=data[op][k*2+1].lazy=0;
}
else
{
data[op][k*2].x=data[op][k*2].r-data[op][k*2].l+1;
data[op][k*2+1].x=data[op][k*2+1].r-data[op][k*2+1].l+1;
data[op][k*2].lazy=data[op][k*2+1].lazy=1;
}
data[op][k].lazy=-1; } void updata(int l,int r,int k,int op)
{
int mid;
if (data[op][k].l==l && data[op][k].r==r)
{
data[op][k].x=data[op][k].r-data[op][k].l+1;
data[op][k].lazy=1;
return;
} Pushdown(k,op); mid=(data[op][k].l+data[op][k].r)/2; if (r<=mid) updata(l,r,k*2,op);
else
if (l>mid) updata(l,r,k*2+1,op);
else
{
updata(l,mid,k*2,op);
updata(mid+1,r,k*2+1,op);
} data[op][k].x=data[op][k*2].x+data[op][k*2+1].x; } void search(int l,int r,int k,int op)
{
int mid;
if (data[op][k].l==l && data[op][k].r==r)
{
temp+=data[op][k].x;
data[op][k].x=0;
data[op][k].lazy=0;
return ;
} Pushdown(k,op); mid=(data[op][k].l+data[op][k].r)/2; if (r<=mid) search(l,r,k*2,op);
else if (l>mid) search(l,r,k*2+1,op);
else
{
search(l,mid,k*2,op);
search(mid+1,r,k*2+1,op);
} data[op][k].x=data[op][k*2].x+data[op][k*2+1].x;
}
void init()
{
int i;
scanf("%s",str);
for (i=0;i<26;i++)
build(1,n,1,i);
for (i=0;i<n;i++)
updata(i+1,i+1,1,str[i]-'a');
}
int main()
{
int m,a,b,c,i,j,k;
int mark[30];
while (scanf("%d%d",&n,&m)!=EOF)
{
init(); while (m--)
{
scanf("%d%d%d",&a,&b,&c);
memset(mark,0,sizeof(mark));
for (i=0;i<26;i++)
{
temp=0;
search(a,b,1,i); // 查找区间内i字母出现的次数,并清空
mark[i]+=temp;
}
if (c==0)
{
k=a;
for (i=25;i>=0;i--)
if (mark[i]!=0)
{
updata(k,k+mark[i]-1,1,i); // 更新区间字母
k+=mark[i];
}
}
else
{
k=a;
for (i=0;i<26;i++)
if (mark[i]!=0)
{
updata(k,k+mark[i]-1,1,i);
k+=mark[i]; }
}
}
for (i=1;i<=n;i++)
{
for (j=0;j<26;j++)
{
temp=0;
search(i,i,1,j);
if (temp!=0)
{
printf("%c",j+'a');
break;
}
}
}
printf("\n");
}
return 0;
}

Codeforces 558E 线段树处理字符串内排序的更多相关文章

  1. Bash and a Tough Math Puzzle CodeForces 914D 线段树+gcd数论

    Bash and a Tough Math Puzzle CodeForces 914D 线段树+gcd数论 题意 给你一段数,然后小明去猜某一区间内的gcd,这里不一定是准确值,如果在这个区间内改变 ...

  2. Codeforces Round #424 (Div. 2, rated, based on VK Cup Finals) Problem E (Codeforces 831E) - 线段树 - 树状数组

    Vasily has a deck of cards consisting of n cards. There is an integer on each of the cards, this int ...

  3. cf580E. Kefa and Watch(线段树维护字符串hash)

    题意 $n$个数的序列,$m + k$种操作 1.$l , r, k$把$l - r$赋值为$k$ 2.$l, r, d$询问$l - r$是否有长度为$d$的循环节 Sol 首先有个神仙结论:若询问 ...

  4. Codeforces 750E 线段树DP

    题意:给你一个字符串,有两种操作:1:把某个位置的字符改变.2:询问l到r的子串最少需要删除多少个字符,使得这个子串含有2017子序列,并且没有2016子序列? 思路:线段树上DP,我们设状态0, 1 ...

  5. Codeforces 938G 线段树分治 线性基 可撤销并查集

    Codeforces 938G Shortest Path Queries 一张连通图,三种操作 1.给x和y之间加上边权为d的边,保证不会产生重边 2.删除x和y之间的边,保证此边之前存在 3.询问 ...

  6. codeforces 1136E 线段树

    codeforces 1136E: 题意:给你一个长度为n的序列a和长度为n-1的序列k,序列a在任何时候都满足如下性质,a[i+1]>=ai+ki,如果更新后a[i+1]<ai+ki了, ...

  7. Z - New Year Tree CodeForces - 620E 线段树 区间种类 bitset

    Z - New Year Tree CodeForces - 620E 这个题目还没有写,先想想思路,我觉得这个题目应该可以用bitset, 首先这个肯定是用dfs序把这个树转化成线段树,也就是二叉树 ...

  8. D - The Bakery CodeForces - 834D 线段树优化dp···

    D - The Bakery CodeForces - 834D 这个题目好难啊,我理解了好久,都没有怎么理解好, 这种线段树优化dp,感觉还是很难的. 直接说思路吧,说不清楚就看代码吧. 这个题目转 ...

  9. B - Legacy CodeForces - 787D 线段树优化建图+dij最短路 基本套路

    B - Legacy CodeForces - 787D 这个题目开始看过去还是很简单的,就是一个最短路,但是这个最短路的建图没有那么简单,因为直接的普通建图边太多了,肯定会超时的,所以要用线段树来优 ...

随机推荐

  1. ansible 工作原理以及使用详解

    内容:1.ansible的作用以及工作结构2.ansible的安装以及使用3.ansible的playbook使用 一.ansible的作用以及工作结构        1.ansible简介:     ...

  2. python 多列表对应的位置的值形成一个新的列表

    list1 = [1, 2, 3, 4, 5] list2 = ['a','b', 'c', 'd', 'e'] list3 = [1, 2, 3, 4, 5] multi_list = map(li ...

  3. windows编程ASCII问题

    在CMD中输入CHCP可查看当前使用代码 输入CHCP 65001为UTF-8

  4. Maven学习总结(25)——Eclipse Maven Update 时JDK版本变更问题

    1.新建一个Maven项目JDK版本和系统版本不对应, 2.右键Maven项目->Maven->Update ProjectJDK版本改变了, 3.操作系统的JDK重装了新的版本,这是引起 ...

  5. 关于C++的一些函数的使用方法

    关于C++的一些函数的使用方法: http://www.shouce.ren/api/c/index.html

  6. what&#39;s new in vc2015

    1. 变量和函数的注解提示非常实用.象C#了. 2.CStdioFile升级了,不再须要象 vc2013中,用CStdioFileEx来修复错误了. 3. 发现再写. 

  7. PC端 java 开发蓝牙所遇到的问题

    由于项目的原因.要在电脑上开发一个通过蓝牙传送数据的client.我採用的是JAVA,JSME开发. client:去搜素蓝牙信号,然后找到对应的蓝牙信号进行连接. 服务端:client须要进行连接的 ...

  8. Python中常见的文件对象内建函数

    文件对象内建方法列表 文件对象的方法 操作 file.close() 关闭文件 file.fileno() 返回文件的描写叙述符(file descriptor.FD,整数值) file.flush( ...

  9. php给图片加入文字水印

    PHP对图片的操作用到GD库.这里我们介绍怎样给图片加入文字水印. 大致分为四步: 1.打开图片 2.操作图片 3.输出图片 4.销毁图片 以下我们上代码来详细解说每步的实现过程: <? php ...

  10. linux 挂载存储步骤(以emc 5300为例)

    挂载存储有两种方式:光纤模式(hub卡)和iscsi (以太网).两者大体思路是一样的. 1.在应用服务器上安装hub卡,连接光纤到光纤交换机上: 2.在应用服务器安装hub卡驱动程序: 3.在存储上 ...