A Simple Task(Codeforces Round #312 (Div. 2) 线段树+计数排序)

这是一个关于字符串操作的问题,给定一个长度为n的字符串S和q个查询,每个查询涉及对字符串中从i到j的子串进行非递增或非递减排序。任务是根据所有查询后的结果输出最终字符串。输入包括n、q、字符串S和q组查询,每组查询包含i、j和k(0或1)。输出经过所有查询处理后的S。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

E. A Simple Task
time limit per test
5 seconds
memory limit per test
512 megabytes
input
standard input
output
standard output

This task is very simple. Given a string S of length n and q queries each query is on the format i j k which means sort the substring consisting of the characters from i to j in non-decreasing order if k = 1 or in non-increasing order if k = 0.

Output the final string after applying the queries.

Input

The first line will contain two integers n, q (1 ≤ n ≤ 1050 ≤ q ≤ 50 000), the length of the string and the number of queries respectively.

Next line contains a string S itself. It contains only lowercase English letters.

Next q lines will contain three integers each i, j, k (1 ≤ i ≤ j ≤ n).

Output

Output one line, the string S after applying the queries.

Sample test(s)
input
10 5
abacdabcda
7 10 0
5 8 1
1 4 0
3 6 0
7 10 1
output
cbcaaaabdd
input
10 1
agjucbvdfk
1 10 1
output
abcdfgjkuv
Note

First sample test explanation:





    题意:输出一段字符串经过m次排序后的序列,x,y,k.当k==1时代表x-y区间

的字 符串进行降序排列看k== 0时代表x-y的区间进行升序排列



#include<iostream>
#include<algorithm>
#include<stdio.h>
#include<string.h>
#include<stdlib.h>

#define N 100005

struct node
{
    int l;
    int r;
    int mid;
    int ans;
    int lz;
}q[26][N<<2];

char str[N];
int n,m;
int num[26];
char ss[N];

void build(int l,int r,int rt,int id)
{
    int mid = (l+r)>>1;
    q[id][rt].l = l;
    q[id][rt].r = r;
    q[id][rt].lz = -1;
    q[id][rt].mid = mid;
    if(l+1 == r)
    {
        q[id][rt].ans = (str[l-1] == 'a'+id);
        return ;
    }
    build(l,mid,rt<<1,id);
    build(mid,r,rt<<1|1,id);
    q[id][rt].ans = q[id][rt<<1].ans + q[id][rt<<1|1].ans;
}

void push_down(int rt,int id)
{
    if(q[id][rt].lz>=0)
    {
        q[id][rt<<1].ans = (q[id][rt<<1].r - q[id][rt<<1].l)*q[id][rt].lz;
        q[id][rt<<1].lz = q[id][rt].lz;
        q[id][rt<<1|1].ans = (q[id][rt<<1|1].r - q[id][rt<<1|1].l)*q[id][rt].lz;
        q[id][rt<<1|1].lz = q[id][rt].lz;
        q[id][rt].lz = -1;
    }
}

int qqurry(int l,int r,int rt,int id)
{
    //printf("rt = %d    l = %d    r = %d    mid = %d    ll = %d    rr = %d\n",rt,l,r,q[id][rt].mid,q[id][rt].l,q[id][rt].r);
    if(q[id][rt].l == l && q[id][rt].r == r)
    {
        return q[id][rt].ans;
    }
    push_down(rt,id);
    if(r<=q[id][rt].mid)
    {
        return qqurry(l,r,rt<<1,id);
    }
    if(l>=q[id][rt].mid)
    {
        return qqurry(l,r,rt<<1|1,id);
    }
    return (qqurry(l,q[id][rt].mid,rt<<1,id) + qqurry(q[id][rt].mid,r,rt<<1|1,id));
}

void updata(int l,int r,int rt,int pp,int id)
{
    if(q[id][rt].l == l && q[id][rt].r == r)
    {
        q[id][rt].ans = (q[id][rt].r - q[id][rt].l)*pp;
        q[id][rt].lz = pp;
        return ;
    }
    push_down(rt,id);
    if(r<=q[id][rt].mid)
    {
        updata(l,r,rt<<1,pp,id);
    }
    else if(l>=q[id][rt].mid)
    {
        updata(l,r,rt<<1|1,pp,id);
    }
    else
    {
        updata(l,q[id][rt].mid,rt<<1,pp,id);
        updata(q[id][rt].mid,r,rt<<1|1,pp,id);
    }
    q[id][rt].ans = q[id][rt<<1].ans + q[id][rt<<1|1].ans;
}

int main()
{
    while(scanf("%d%d",&n,&m)!=EOF)
    {
        scanf("%s",str);
        for(int i=0;i<26;i++)
        {
            build(1,n+1,1,i);
        }
        int x,y,k;
        while(m--)
        {
            scanf("%d%d%d",&x,&y,&k);
            for(int i=0;i<26;i++)
            {
                num[i] = qqurry(x,y+1,1,i);
                updata(x,y+1,1,0,i);
            }
            if(k == 1)
            {
                int cnt = x;
                for(int i=0;i<26;i++)
                {
                    if(num[i]>0)
                    {
                        updata(cnt,cnt+num[i],1,1,i);
                    }
                    cnt += num[i];
                }
            }
            else if(k == 0)
            {
                int cnt = x;
                for(int i=25;i>=0;i--)
                {
                    if(num[i]>0)
                    {
                        updata(cnt,cnt+num[i],1,1,i);
                    }
                    cnt += num[i];
                }
            }
        }
        for(int i=1;i<=n;i++)
        {
            for(int j=0;j<26;j++)
            {
                if(qqurry(i,i+1,1,j))
                {
                    ss[i-1] = 'a' + j;
                    break;
                }
            }
        }
        printf("%s\n",ss);
    }
    return 0;
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

叶孤心丶

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值