• codeforce452DIV2——F. Letters Removing


    题意:
    给一个字符串和m个操作,每次给出l,r,c,把字符串中l-r这段区间的字符为c的字符删掉,求最后的字符串。(n,m<=2e5)
    线段树。注意这个区间修改和普通区间修改的区别。

    他们都是用树状数组做的哎,可是我对树状数组一直是一脸懵逼

     1 #include <cstdio>
     2 #include <cstring>
     3 #include <algorithm>
     4 #include <iostream>
     5 using namespace std;
     6 const int maxn=200000+100;
     7 const int maxnode=65;
     8 int n,m;
     9 char s[maxn];
    10 int a[maxn];
    11 int get(char c){
    12     if(c>='A'&&c<='Z')return c-'A';
    13     if(c>='a'&&c<='z')return c-'a'+26;
    14     if(c>='0'&&c<='9')return c-'0'+52;
    15 }
    16 char res(int x){
    17     if(x>=0&&x<26)return x+'A';
    18     if(x>=26&&x<52)return x-26+'a';
    19     if(x>=52&&x<62)return x-52+'0';
    20 }
    21 int sumv[4*maxn],num[4*maxn][maxnode];
    22 void build(int o,int L,int R){
    23     if(L==R){
    24         sumv[o]=1;
    25         num[o][a[L]]=1;
    26         return ;
    27     }
    28     int M=L+(R-L)/2;
    29     build(2*o,L,M);
    30     build(2*o+1,M+1,R);
    31     sumv[o]=sumv[2*o]+sumv[2*o+1];
    32     for(int i=0;i<62;i++)
    33         num[o][i]=num[2*o][i]+num[2*o+1][i];
    34 }
    35 int ql,qr,c;
    36 void update(int o,int L,int R){
    37     if(num[o][c]==0)return ;
    38     if(ql>R||qr<L)
    39         return ;
    40     if(L==R){
    41         if(num[o][c]){
    42         sumv[o]=0;
    43         num[o][c]=0;
    44         }
    45         return ;
    46     }
    47     int M=L+(R-L)/2;
    48     update(2*o,L,M);
    49     update(2*o+1,M+1,R);
    50     sumv[o]=sumv[2*o]+sumv[2*o+1];
    51     num[o][c]=num[2*o][c]+num[2*o+1][c];
    52 }
    53 int find(int o,int L,int R ,int k){
    54     int M=L+(R-L)/2;
    55     if(L==R)return L;
    56     if(sumv[2*o]>=k)return find(2*o,L,M,k);
    57     else return find(2*o+1,M+1,R,k-sumv[2*o]);
    58 }
    59 void tra(int o,int L,int R){
    60     if(sumv[o]==0)return ;
    61     if(L==R){
    62         for(int i=0;i<62;i++)
    63         if(num[o][i]){
    64             int c=res(i);
    65             printf("%c",c);
    66         }
    67         return ;
    68     }
    69     int M=L+(R-L)/2;
    70     tra(2*o,L,M);
    71     tra(2*o+1,M+1,R);
    72 }
    73 int main(){
    74     scanf("%d%d",&n,&m);
    75     scanf("%s",s+1);
    76     for(int i=1;i<=n;i++)a[i]=get(s[i]);
    77     build(1,1,n);
    78     int L,R;
    79     char cc;
    80     for(int i=1;i<=m;i++){
    81         scanf("%d%d %c",&L,&R,&cc);
    82         L=find(1,1,n,L),R=find(1,1,n,R);
    83         ql=L,qr=R,c=get(cc);
    84         update(1,1,n);
    85     }
    86     tra(1,1,n);
    87 return 0;
    88 }
    View Code
  • 相关阅读:
    第二章 1.绘制文本
    在Windows Mobile 5中使用DirectShow控制摄像头转
    写会议纪要也是需要水平滴
    注重实效的程序员(The Pragmatic Programmer)[转载]
    项目经理面试指南(上)[转载]
    上海西门子培训序
    周末桂林游
    我们应该如何面试程序员/技术人员?
    Erlang Code Auto Reloader
    新车落地几种常见的配件加装建议
  • 原文地址:https://www.cnblogs.com/LQLlulu/p/8785728.html
Copyright © 2020-2023  润新知