zoukankan      html  css  js  c++  java
  • string

    string

    【题目描述】

    给定一个由小写字母组成的字符串s。有m次操作,每次操作给定3个参数l,r,x。如果x=1,将s[l] ~ s[r]升序排序;如果x=0,将s[l] ~ s[r]降序排序。你需要求出最终序列。

    【输入数据】

    第一行两个整数n,m。第二行一个字符串s。接下来m行每行三个整数x,l,r。

    【输出数据】

    一行一个字符串表示答案。

    【样例输入】

    5 2

    cabcd

    1 3

    1

    3 5

    0

    【样例输出】

    abdcc

    【数据范围】

    对于40%的数据,n,m<=1000。

    对于100%的数据,n,m<=100000

    题解

    image

    这道题卡常卡得好严,打出正解也过不掉啊,我果然还是太菜了

    就比暴力多二十分的代码

    #include <iostream>
    #include <cstdio>
    #include <cstdlib>
    #include <cstring>
    #include <algorithm>
    #include <cmath> 
    #define N 100100
    using namespace std; 
    
    int n,m,tmp[27];
    char s[N];
    
    struct Segment_tree
    {
    	struct node
    	{
    		int l,r,sum,f;
    	}T[N<<2];
    	void pushup(int p){T[p].sum=T[p<<1].sum+T[p<<1|1].sum;}
    	void build(int p,int x,int y,char v)
    	{
    		T[p].l=x;T[p].r=y;T[p].f=-1;
    		if(x==y){if(s[x]==v)T[p].sum=1;return;}
    		int mid=(x+y)>>1;
    		build(p<<1,x,mid,v);
    		build(p<<1|1,mid+1,y,v);
    		pushup(p);
    	}
    	void pushdown(int p)
    	{
    		if(T[p].f==-1) return;
    		T[p<<1].sum=(T[p<<1].r-T[p<<1].l+1)*T[p].f;
    	    T[p<<1|1].sum=(T[p<<1|1].r-T[p<<1|1].l+1)*T[p].f;
    	    T[p<<1].f=T[p<<1|1].f=T[p].f;
    	    T[p].f=-1;
    	}
    	int query(int p,int x,int y)
    	{
    		int pl=T[p].l,pr=T[p].r;
    		if(pl==x&&pr==y) return T[p].sum;
    		pushdown(p);
    		int mid=(pl+pr)>>1;
    		if(y<=mid) return query(p<<1,x,y);
    		else if(x>mid) return query(p<<1|1,x,y);
    		return query(p<<1,x,mid)+query(p<<1|1,mid+1,y);
    	}
    	void set(int p,int x,int y,int v)
    	{
    		int pl=T[p].l,pr=T[p].r;
    	    if(pl==x&&pr==y)
    	    {
    	        T[p].sum=(T[p].r-T[p].l+1)*v;
    	        T[p].f=v;
    	        return;
    	    } 
    	    pushdown(p);
    	    int mid=(pl+pr)>>1;
    	    if(y<=mid) set(p<<1,x,y,v);
    	    else if(x>mid) set(p<<1|1,x,y,v);
    	    else
    	    {
    	        set(p<<1,x,mid,v);
    	        set(p<<1|1,mid+1,y,v);
    	    }
    	    pushup(p);
    	}
    	void get_ans(int p,int x,int y,char v)
    	{
    		if(x==y){if(T[p].sum)s[x]=v;return;}
    		pushdown(p);
    		int mid=(x+y)>>1;
    		get_ans(p<<1,x,mid,v);
    		get_ans(p<<1|1,mid+1,y,v);
    		pushup(p);
    	}
    	
    }st[27];
    
    int main()
    {
    	scanf("%d%d%s",&n,&m,s+1);
    	for(int i=0;i<26;i++) st[i].build(1,1,n,'a'+i);//对于每个字母,用一颗线段树维护 
    	while(m--)
    	{
    		int l,r,opt;scanf("%d%d%d",&l,&r,&opt);
    		for(int i=0;i<26;i++) tmp[i]=st[i].query(1,l,r);//先求出区间内字母i的个数
    		for(int i=0;i<26;i++) st[i].set(1,l,r,0);//将区间清空 
    		if(opt)//升序
    		{
    			int pos=l;
    			for(int i=0;i<26;i++) if(tmp[i]) st[i].set(1,pos,pos+tmp[i]-1,1),pos+=tmp[i];
    		}
    		else//降序 
    		{
    			int pos=l;
    			for(int i=25;i>=0;i--) if(tmp[i]) st[i].set(1,pos,pos+tmp[i]-1,1),pos+=tmp[i];
    		}
    	}
    	for(int i=0;i<26;i++) st[i].get_ans(1,1,n,'a'+i);
    	for(int i=1;i<=n;i++) printf("%c",s[i]);
    	return 0;
    }
  • 相关阅读:
    模拟75 题解
    模拟74 题解
    模拟73 题解
    模拟72 题解
    前端学习:html基础学习二
    前端学习:html基础学习一
    JavaScrip:Function函数编程
    MYSQL:RELPACE用法
    MYSQL:插入记录检查记录是否存在,存在则更新,不存在测插入记录SQL
    OpenCASCADE Curve Length Calculation
  • 原文地址:https://www.cnblogs.com/XYZinc/p/7721872.html
Copyright © 2011-2022 走看看