给出长度为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. linux内核(四)内存管理单元MMU

    1,基本概念 一个程序运行时没必要全部都同时装入内存,只需要把当前需要运行的部分装入内存即可,这样就使得一个大程序可以在较小的内存中运行,也使得内存中可以同时装入更多的程序并发执行,从用户角度看,该系 ...

  2. POJ 2230 Watchcow

    Watchcow Time Limit: 3000ms Memory Limit: 65536KB This problem will be judged on PKU. Original ID: 2 ...

  3. Qt之qInstallMessageHandler(输出详细日志)

    简述 安装之前已定义的消息处理程序,返回一个指向前一个消息处理程序. 消息处理程序是一个函数,用于打印调试信息.警告信息.严重错误和致命的错误的消息.Qt库(debug模式)包含成百上千的警告信息打印 ...

  4. 亚马逊AWS学习——多网络接口下配置EC2实例连接公网的一个“bug”

    转载请注明出处:http://blog.csdn.net/dongdong9223/article/details/47667627 本文出自[我是干勾鱼的博客] 之前在<亚马逊AWS学习--E ...

  5. hdu1281 棋盘游戏 --- 最大匹配

    给一个矩形棋盘,上面有一些空格点,能够放象棋中的"车", 现给出空格的坐标,求最多能够放多少个"车"使他们互不攻击(依据象棋规则,每行每列至多仅仅能放一个), ...

  6. LeetCode OJ 215. Kth Largest Element in an Array 堆排序求解

    题目链接:https://leetcode.com/problems/kth-largest-element-in-an-array/ 215. Kth Largest Element in an A ...

  7. bzoj1570: [JSOI2008]Blue Mary的旅行(二分+网络流)

    1570: [JSOI2008]Blue Mary的旅行 题目:传送门 题解: get到拆点新姿势,还是做题太少了...ORZ 因为每天就只能有一个航班,那就不能直接连了,所以要拆点(然后就被卡住了) ...

  8. 关于markdown的使用

    首先: https://www.cnblogs.com/jordangong/p/9804777.html 注意:提交博客时需将 Markdown 源码粘贴到编辑器中,且编辑器没有实时预览,可以上传后 ...

  9. JavaScript中Array方法总览

    title: JavaScript中Array方法总览 toc: true date: 2018-10-13 12:48:14 push(x) 将x添加到数组最后,可添加多个值,返回数组长度.改变原数 ...

  10. transient修饰符的作用

    transient修饰符的作用: entity实体类: package com.baidu.entity; import com.fasterxml.jackson.annotation.JsonIg ...