zoukankan      html  css  js  c++  java
  • CF558E-A Simple Task

    题目

    开始给出一个长度为(n)的小写字母串,(m)次操作,每次选一个区间,把这个区间进行升序或降序排序。最后输出所有操作结束后的串。

    (nle 10^5,mle 5 imes 10^4)

    分析

    神思路!!

    其实主要是要注意到这个字母表为26非常小,所以可以考虑使用基数排序!事实上排序也可以看成统计每种数有多少个按顺序输出的过程。

    二十六颗线段树,维护区间中每种字母的出现次数。排序的时候遍历所有的字母,把该排在前面的全部移到前面。这可以用一个支持区间求和,区间加法,区间清零的线段树来做,写的时候标记可以用一个二元组来表示,(x=a_0*x+a_1*len)

    总而言之用每个字母的位置来刻画这个序列。

    其实很多字符串问题都是基于字母表比较小来做的。

    代码

    #include<cstdio>
    #include<cctype>
    #include<cstring>
    #include<utility>
    #include<algorithm>
    using namespace std;
    int read() {
    	int x=0,f=1;
    	char c=getchar();
    	for (;!isdigit(c);c=getchar()) if (c=='-') f=-1;
    	for (;isdigit(c);c=getchar()) x=x*10+c-'0';
    	return x*f;
    }
    const int maxn=1e5+1;
    const int maxc=26;
    int n,m;
    char s[maxn];
    pair<int,int> operator + (pair<int,int> a,pair<int,int> b) {
    	return make_pair(a.first*b.first,a.second*b.first+b.second);
    }
    struct SGT {
    	int t[maxn<<2];
    	pair<int,int> tag[maxn<<2];
    	void build(int x,int l,int r) {
    		if (l==r) return;
    		t[x]=0,tag[x]=make_pair(1,0);
    		int mid=(l+r)>>1;
    		build(x<<1,l,mid),build(x<<1|1,mid+1,r);
    	}
    	void doit(int x,int l,int r,pair<int,int> d) {
    		t[x]=t[x]*d.first+(r-l+1)*d.second;
    		tag[x]=tag[x]+d;
    	}
    	void pushdown(int x,int l,int mid,int r) {
    		doit(x<<1,l,mid,tag[x]);
    		doit(x<<1|1,mid+1,r,tag[x]);
    		tag[x]=make_pair(1,0);
    	}
    	void modify(int x,int L,int R,int l,int r,pair<int,int> d) {
    		if (L==l && R==r) {
    			doit(x,L,R,d);
    			return;
    		}
    		int mid=(L+R)>>1;
    		pushdown(x,L,mid,R);
    		if (r<=mid) modify(x<<1,L,mid,l,r,d); else 
    		if (l>mid) modify(x<<1|1,mid+1,R,l,r,d); else
    		modify(x<<1,L,mid,l,mid,d),modify(x<<1|1,mid+1,R,mid+1,r,d);
    		t[x]=t[x<<1]+t[x<<1|1];
    	}
    	void clear(int l,int r) {
    		if (l>r) return;
    		modify(1,1,n,l,r,make_pair(0,0));
    	}
    	void inc(int l,int r) {
    		if (l>r) return;
    		modify(1,1,n,l,r,make_pair(1,1));
    	}
    	int query(int x,int L,int R,int l,int r) {
    		if (L==l && R==r) return t[x];
    		int mid=(L+R)>>1;
    		pushdown(x,L,mid,R);
    		if (r<=mid) return query(x<<1,L,mid,l,r);
    		if (l>mid) return query(x<<1|1,mid+1,R,l,r);
    		return query(x<<1,L,mid,l,mid)+query(x<<1|1,mid+1,R,mid+1,r);
    	}
    	int query(int l,int r) {
    		if (l>r) return 0;
    		return query(1,1,n,l,r);
    	}
    } sgt[maxc];
    int main() {
    #ifndef ONLINE_JUDGE
    	freopen("test.in","r",stdin);
    #endif
    	n=read(),m=read();
    	scanf("%s",s+1);
    	for (int i=0;i<maxc;++i) sgt[i].build(1,1,n);
    	for (int i=1;i<=n;++i) sgt[s[i]-'a'].inc(i,i);
    	while (m--) {
    		int l=read(),r=read(),o=read();
    		if (o) {
    			int alr=0;
    			for (int i=0;i<maxc;++i) {
    				int tmp=sgt[i].query(l,r);
    				sgt[i].clear(l,r);
    				sgt[i].inc(l+alr,l+alr+tmp-1);
    				alr+=tmp;
    			}
    		} else {
    			int alr=0;
    			for (int i=maxc-1;i>=0;--i) {
    				int tmp=sgt[i].query(l,r);
    				sgt[i].clear(l,r);
    				sgt[i].inc(l+alr,l+alr+tmp-1);
    				alr+=tmp;
    			}
    		}
    	}
    	for (int i=1,j;i<=n;++i) {
    		for (j=0;j<maxc;++j) if (sgt[j].query(i,i)) {
    			putchar('a'+j);
    			break;
    		}
    	}
    	puts("");
    	return 0;
    }
    
  • 相关阅读:
    [MacOS]Sublime text3 安装(一)
    [RHEL8]开启BBR
    PAT Advanced 1136 A Delayed Palindrome (20分)
    PAT Advanced 1144 The Missing Number (20分)
    PAT Advanced 1041 Be Unique (20分)
    PAT Advanced 1025 PAT Ranking (25分)
    PAT Advanced 1022 Digital Library (30分)
    PAT Advanced 1019 General Palindromic Number (20分)
    PAT Advanced 1011 World Cup Betting (20分)
    PAT Advanced 1102 Invert a Binary Tree (25分)
  • 原文地址:https://www.cnblogs.com/owenyu/p/7155598.html
Copyright © 2011-2022 走看看