• Codeforces Round #452 F. Letters Removing


    Description

    Petya has a string of length n consisting of small and large English letters and digits.
    He performs m operations. Each operation is described with two integers l and r and a character c: Petya removes from the string all characters c on positions between l and r, inclusive. It's obvious that the length of the string remains the same or decreases after each operation.
    Find how the string will look like after Petya performs all m operations.

    solution

    正解:线段树+set
    我们先要将([l,r])还原的原字符串上,([l,r])对应着原序列的第 (l,r) 个不是空位的位置,线段树维护即可
    对于删除,我们直接对每一个元素开一个set,找出区间后直接暴力删除即可,因为每一个元素只会被删一次,复杂度是 (O(n*logn)).

    #include <algorithm>
    #include <iostream>
    #include <cstdlib>
    #include <cstring>
    #include <cstdio>
    #include <cmath>
    #include <set>
    #define RG register
    #define iter iterator
    #define ls (o<<1)
    #define rs (o<<1|1)
    using namespace std;
    typedef long long ll;
    const int N=200005;
    int n,m,tr[N<<2],T=141;char s[N];
    inline void build(int l,int r,int o){
    	if(l==r){tr[o]=1;return ;}
    	int mid=(l+r)>>1;
    	build(l,mid,ls);build(mid+1,r,rs);
    	tr[o]=tr[ls]+tr[rs];
    }
    set<int>S[142];
    set<int>::iter it;
    inline int qry(int l,int r,int o,int k){
    	if(l==r)return l;
    	int mid=(l+r)>>1,sum=tr[ls];
    	if(sum>=k)return qry(l,mid,ls,k);
       return qry(mid+1,r,rs,k-sum);
    }
    inline void ins(int l,int r,int o,int sa){
    	tr[o]--;if(l==r)return ;
    	int mid=(l+r)>>1;
    	if(sa<=mid)ins(l,mid,ls,sa);
    	else ins(mid+1,r,rs,sa);
    }
    int st[N],top=0;bool d[N];
    void work()
    {
    	scanf("%d%d",&n,&m);
    	scanf("%s",s+1);
    	build(1,n,1);
    	for(int i=1;i<=n;i++)S[(int)s[i]].insert(i);
    	int l,r,c;char ch[2];
    	while(m--){
    		scanf("%d%d%s",&l,&r,ch);c=ch[0];
    		l=qry(1,n,1,l);r=qry(1,n,1,r);
    		it=S[c].lower_bound(l);
    		while(it!=S[c].end() && *it<=r)st[++top]=*it,++it;
    		while(top){
    			ins(1,n,1,st[top]);
    			S[c].erase(st[top]);
    			d[st[top--]]=1;
    		}
    	}
    	for(int i=1;i<=n;i++)if(!d[i])putchar(s[i]);
    }
    
    int main()
    {
    	freopen("pp.in","r",stdin);
    	freopen("pp.out","w",stdout);
    	work();
    	return 0;
    }
    
    
  • 相关阅读:
    Ubuntu16.04下同时安装Anaconda2与Anaconda3
    ansible 常用模块
    docker 笔记 (7) 限制容器
    linux 磁盘
    docker 笔记 (6)搭建本地registry
    docker 笔记 (5)常用命令
    docker 笔记(4) Dockerfile 常用的指令
    NGINX下配置CACHE-CONTROL
    mysql二进制安装
    [Selenium] Explicit wait 方法
  • 原文地址:https://www.cnblogs.com/Yuzao/p/8065000.html
Copyright © 2020-2023  润新知