码迷,mamicode.com
首页 > 其他好文 > 详细

2018百度之星资格赛T2 子串查询

时间:2018-08-05 16:54:36      阅读:124      评论:0      收藏:0      [点我收藏+]

标签:ase   etc   close   i++   nbsp   efi   while   amp   image   

技术分享图片

【题解】

  很容易想到暴力做法:对于每个询问暴力查找区间内的最小字母,统计其出现次数。效率O(N^2),无法通过全部数据。

  我们可以换一个思路,设f[i][j]为第i个字母(字母‘A‘到’Z‘分别对应0到25)到第j个位置的出现次数和。

  对于每个询问[L,R],我们只要从0到25枚举每个字母,如果满足c[i][R]-c[i][L-1]>0,那么这个区间的这个字母出现过,输出其次数并break即可。

技术分享图片
 1 #include<cstdio>
 2 #include<algorithm>
 3 #include<cstring>
 4 #define LL long long
 5 #define rg register
 6 #define N 200010
 7 using namespace std;
 8 int T,t,n,m,l,r,ans,cnt[26][N];
 9 char c[N],mn;
10 inline int read(){
11     int k=0,f=1; char c=getchar();
12     while(c<0||c>9)c==-&&(f=-1),c=getchar();
13     while(0<=c&&c<=9)k=k*10+c-0,c=getchar();
14     return k*f;
15 }
16 inline void Pre(){
17     memset(cnt,0,sizeof(cnt));
18 }
19 int main(){
20     T=t=read();
21     while(T--){
22         printf("Case #%d:\n",t-T);
23         Pre();
24         n=read(); m=read();
25         for(rg int i=1;i<=n;i++){
26             c[i]=getchar();
27             while(c[i]<A||c[i]>Z) c[i]=getchar();
28             cnt[c[i]-A][i]++;
29         }
30         for(rg int i=0;i<26;i++)
31             for(rg int j=1;j<=n;j++) cnt[i][j]+=cnt[i][j-1];
32         while(m--){
33             l=read(),r=read();
34             for(rg int i=0;i<26;i++) if(cnt[i][r]-cnt[i][l-1]>0){
35                 printf("%d\n",cnt[i][r]-cnt[i][l-1]);
36                 break;
37             }
38         }
39     }
40     return 0;
41 }
42 Close
View Code

 

2018百度之星资格赛T2 子串查询

标签:ase   etc   close   i++   nbsp   efi   while   amp   image   

原文地址:https://www.cnblogs.com/DriverLao/p/9425979.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!