zoukankan      html  css  js  c++  java
  • 【2018百度之星资格赛】1002 子串查询

    题目

      度度熊的字符串课堂开始了!要以像度度熊一样的天才为目标,努力奋斗哦!

    为了检验你是否具备不听课的资质,度度熊准备了一个只包含大写英文字母的字符串 A[1,n]=a1a2⋯anA[1,n] = a_1 a_2 cdots a_nA[1,n]=a1​​a2​​an​​,接下来他会向你提出 qqq 个问题 (l,r)(l,r)(l,r),你需要回答字符串 A[l,r]=alal+1⋯arA[l,r] = a_l a_{l+1} cdots a_rA[l,r]=al​​al+1​​ar​​ 内有多少个非空子串是 A[l,r]A[l,r]A[l,r] 的所有非空子串中字典序最小的。这里的非空子串是字符串中由至少一个位置连续的字符组成的子序列,两个子串是不同的当且仅当这两个子串内容不完全相同或者出现在不同的位置。

    ∣S∣|S|S∣ 为字符串 SSS 的长度,对于两个字符串 SSS 和 TTT ,定义 SSS 的字典序比 TTT 小,当且仅当存在非负整数 k(≤min(∣S∣,∣T∣))k(leq min(|S|,|T|))k(min(S,T)) 使得 SSS 的前 kkk 个字符与 TTT 的前 kkk 个字符对应相同,并且要么满足 ∣S∣=k|S| = kS=k 且 ∣T∣>k|T| > kT>k,要么满足 k<min(∣S∣,∣T∣)k < min(|S|,|T|)k<min(S,T) 且 SSS 的第 k+1k+1k+1 个字符比 TTT 的第 k+1k+1k+1 个字符小。例如 "AA" 的字典序比 "AAA" 小,"AB" 的字典序比 "BA" 小。

    分析

      对于每个查询题目说是求最小字串的数量,其实就是求这个区间内最小的字母出现的数目。然后就随便搞一下就可以了。

      我是直接建了个线段树,可以查询区间最小值,因为只包含大写字母,所以我也记录一下每个区间每个字母出现的次数。对于每个查询,先找出这个区间最小的字母是哪个,然后查询它出现的次数就可以了。

      rmq啥的应该也可以搞这个题。

      ac代码

      

     1 #include <cstdio>
     2 #include <cstring>
     3 #include <algorithm>
     4 #include <iostream>
     5 
     6 using namespace std;
     7 const int maxn=100000+100;
     8 const int INF=2147400000;
     9 int T,n,q;
    10 char s[maxn];
    11 int minv[4*maxn],sumv[4*maxn][27];
    12 void maintain(int o,int L,int R){
    13     minv[o]=min(minv[2*o],minv[2*o+1]);
    14     for(int i=0;i<26;i++)
    15         sumv[o][i]=sumv[2*o][i]+sumv[2*o+1][i];
    16 }
    17 void build(int o,int L,int R){
    18     if(L==R){
    19         minv[o]=s[L]-'A';
    20         sumv[o][s[L]-'A']=1;
    21         return;
    22     }
    23     int M=L+(R-L)/2;
    24     build(2*o,L,M);
    25     build(2*o+1,M+1,R);
    26     maintain(o,L,R);
    27 }
    28 int ql,qr;
    29 int q_min(int o,int L,int R){
    30     if(ql<=L&&qr>=R)
    31         return minv[o];
    32     int M=L+(R-L)/2;
    33     int ml=INF,mr=INF;
    34     if(ql<=M)
    35         ml=q_min(2*o,L,M);
    36     if(qr>M)
    37         mr=q_min(2*o+1,M+1,R);
    38     return min(ml,mr);
    39 }
    40 int v;
    41 int q_sum(int o,int L,int R){
    42     if(ql<=L&&qr>=R){
    43         return sumv[o][v];
    44     }
    45     int res=0;
    46     int M=L+(R-L)/2;
    47     if(ql<=M)
    48         res+=q_sum(2*o,L,M);
    49     if(qr>M)
    50         res+=q_sum(2*o+1,M+1,R);
    51     return res;
    52 }
    53 int main(){
    54     scanf("%d",&T);
    55     for(int t=1;t<=T;t++){
    56         printf("Case #%d:
    ",t);
    57         scanf("%d%d",&n,&q);
    58         scanf("%s",s+1);
    59         memset(sumv,0,sizeof(sumv));
    60         build(1,1,n);
    61         for(int i=1;i<=q;i++){
    62             scanf("%d%d",&ql,&qr);
    63             v=q_min(1,1,n);
    64             printf("%d
    ",q_sum(1,1,n));
    65         }
    66     }
    67 return 0;
    68 }
    69 //CODE FROM LQLlulu
    View Code

      

  • 相关阅读:
    java 正则 二次转义
    HDU1789 Doing Homework again 【贪心】
    扣丁学堂笔记第22天多媒体播放
    [Python]BeautifulSoup—HTML解析包
    Android高级控件(三)——&#160;使用Google ZXing实现二维码的扫描和生成相关功能体系
    Business Process and SAP ERP
    HTML基础知识总结一
    控制器View是怎样创建的?
    cocos2d-x 3.0 场景切换特效汇总
    LeetCode 3Sum
  • 原文地址:https://www.cnblogs.com/LQLlulu/p/9418674.html
Copyright © 2011-2022 走看看