zoukankan      html  css  js  c++  java
  • codeforces 899F Letters Removing set+树状数组

    F. Letters Removing
    time limit per test
    2 seconds
    memory limit per test
    256 megabytes
    input
    standard input
    output
    standard output

    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.

    Input

    The first string contains two integers n and m (1 ≤ n, m ≤ 2·105) — the length of the string and the number of operations.

    The second line contains the string of length n, consisting of small and large English letters and digits. Positions in the string are enumerated from 1.

    Each of the next m lines contains two integers l and r (1 ≤ l ≤ r), followed by a character c, which is a small or large English letter or a digit. This line describes one operation. It is guaranteed that r doesn't exceed the length of the string s before current operation.

    Output

    Print the string Petya will obtain after performing all m operations. If the strings becomes empty after all operations, print an empty line.

    Examples
    input
    4 2
    abac
    1 3 a
    2 2 c
    output
    b
    input
    3 2
    A0z
    1 3 0
    1 1 z
    output
    Az
    input
    10 4
    agtFrgF4aF
    2 5 g
    4 9 F
    1 5 4
    1 7 a
    output
    tFrg4
    input
    9 5
    aAAaBBccD
    1 4 a
    5 6 c
    2 3 B
    4 4 D
    2 3 A
    output
    AB
    Note

    In the first example during the first operation both letters 'a' are removed, so the string becomes "bc". During the second operation the letter 'c' (on the second position) is removed, and the string becomes "b".

    In the second example during the first operation Petya removes '0' from the second position. After that the string becomes "Az". During the second operations the string doesn't change.

    大意:给出一个有数字和字符组成的字符串,M个操作,每次操作给定[L,R]区间,要求删除其中所有的某种字符。

    题解:

    看到这道题我想用      树状数组+链表解决,但是由于链表顺序查找太慢,会被极端数据卡掉,可以用siz(字符集大小)个set代替(明明就是楼主脑洞错了嘛)。

    下面开始正经的正解

    正解: 树状数组+平衡树(set)

    用平衡树可以轻而易举的找到对应区间的字符(upper_bound 或 lower_bound)。

    但是由于删除,区间是在移动的,如何维护?

    树状数组即可,起始前 i 个的累加和是 i ,如果删除 j 就把 j 位置上的 1 减去。

    那么前 i 个的累加和就是第 i 个字符现在的位置。但是我们的需要是找到现在第 i 个字符原来的位置 ,这个操作树状数组也可以做而且是log级的。

    详见代码。

    那么问题就圆满解决了,对了,最后别忘了吧set里面剩下的所有字符都拿出来排序输出。

     1 /*
     2 Welcome Hacking
     3 Wish You High Rating
     4 */
     5 #include<iostream>
     6 #include<cstdio>
     7 #include<cstring>
     8 #include<ctime>
     9 #include<cstdlib>
    10 #include<algorithm>
    11 #include<cmath>
    12 #include<string>
    13 #include<set>
    14 using namespace std;
    15 int read(){
    16     int xx=0,ff=1;char ch=getchar();
    17     while(ch>'9'||ch<'0'){if(ch=='-')ff=-1;ch=getchar();}
    18     while(ch>='0'&&ch<='9'){xx=(xx<<3)+(xx<<1)+ch-'0';ch=getchar();}
    19     return xx*ff;
    20 }
    21 set<int>s[128];
    22 set<int>::iterator it,iter;
    23 const int maxn=200010;
    24 int N,M,temp;
    25 struct BIT{
    26     int b[maxn];
    27     void clear()
    28     {memset(b,0,sizeof(b));}
    29     inline int lowbit(int x)
    30     {return x&(-x);}
    31     void upd(int x,int p){
    32         while(x<=N){
    33             b[x]+=p;
    34             x+=lowbit(x);
    35         }
    36     }
    37     int query(int x){
    38         int re=0;
    39         while(x){
    40             re+=b[x];
    41             x-=lowbit(x);
    42         }
    43         return re;
    44     }
    45     int lower_bound(int v){
    46         int x=0,sum=0;
    47         for(int i=(1<<17);i;i>>=1)
    48             if(i+x<=N&&sum+b[i+x]<v)
    49                 sum+=b[x+=i];
    50         return x+1;
    51     }
    52 }bit;
    53 struct my{
    54     int p;
    55     char c;
    56     bool friend operator<(const my&A,const my&B)
    57     {return A.p<B.p;}
    58 }m[maxn];
    59 int cnt=0;
    60 int main(){
    61     //freopen("in.txt","r",stdin);
    62     N=read(),M=read();
    63     char ch;int t1,t2;
    64     for(int i=1;i<=N;i++){
    65         ch=getchar();
    66         s[ch].insert(i);
    67         bit.upd(i,1);
    68     }
    69     while(M--){
    70         t1=read(),t2=read();ch=getchar();
    71         t1=bit.lower_bound(t1),t2=bit.lower_bound(t2);
    72         it=s[ch].lower_bound(t1);
    73         while(it!=s[ch].end()&&(*it)<=t2){
    74             bit.upd(*it,-1);
    75             s[ch].erase(it++);
    76         }
    77     }
    78     for(char i='0';i<='9';i++)
    79         for(it=s[i].begin();it!=s[i].end();it++)
    80             m[++cnt].c=i,m[cnt].p=*it;
    81     for(char i='a';i<='z';i++)
    82         for(it=s[i].begin();it!=s[i].end();it++)
    83             m[++cnt].c=i,m[cnt].p=*it;
    84     for(char i='A';i<='Z';i++)
    85         for(it=s[i].begin();it!=s[i].end();it++)
    86             m[++cnt].c=i,m[cnt].p=*it;
    87     sort(m+1,m+1+cnt);
    88     for(int i=1;i<=cnt;i++)
    89         printf("%c",m[i].c);
    90     return 0;
    91 }
    View Code
  • 相关阅读:
    JSP第七次作业
    JSP第六次作业
    Jsp第五次作业
    软件测试第二次作业
    Jsp第四次作业2
    Jsp第四次作业1
    软件测试第一次作业
    JSP第三次作业
    JSP第二次作业
    第七次作业
  • 原文地址:https://www.cnblogs.com/lzhAFO/p/8306107.html
Copyright © 2011-2022 走看看