1186.字串数量
时间限制:20000MS内存限制:256000KB
题目描述
有一个由大写字母组成的长度为n的字符串,每次询问l,r,需要回答有多少个非空子串是l到r这个子串里面字典序最小的。这里的非空子串是字符串中由至少一个位置连续的字符组成的子序列,两个子串是不同的当且仅当这两个子串内容不完全相同或者出现在不同的位置。比如"AA" 的字典序比 "AAA" 小,"AB" 的字典序比 "AC" 小。
输入
第一行包含一个整数 T,表示有 T 组测试数据。
接下来依次描述 T 组测试数据。对于每组测试数据:
第一行包含两个整数 n 和 q,表示字符串的长度以及询问的次数。
第二行包含一个长为 n 的只包含大写英文字母的字符串
接下来 q 行,每行包含两个整数l,r
输出
对于每组测试数据,输出q 行,每行包含一个整数,表示l到r这个子串中字典序最小的子串个数,行末不要有多余空格。
输入样例复制
1
2 3
AB
1 1
1 2
2 2
输出样例复制
1
1
1
说明
30%数据满足 T<=1,n<=1e3, q<=1e5 70% T<=2, n<=1e5, q<=1e5 100% T<=2, n<=1e6, q<=1e6 注意优化输入输出
题解:仔细审题,题目即求区间内最小字母的个数,对每种字母做前缀和,统计时找到最小的数量不为0的字母即可
const
maxn=1000000;
var
a:array[1..maxn]of char;
sum:array['A'..'Z',0..maxn]of longint;
i,l,r,n,t,q,kk:longint;
j:char;
procedure init;
var
i:longint;
j:char;
begin
readln(n,q);
for i:=1 to n do
begin
read(a[i]);
for j:='A' to 'Z' do
sum[j,i]:=sum[j,i-1];
sum[a[i],i]:=sum[a[i],i]+1;
end;
end;
begin
readln(t);
for kk:=1 to t do
begin
init;
for i:=1 to q do
begin
readln(l,r);
for j:='A' to 'Z' do
if sum[j,r]-sum[j,l-1]>0 then
begin
writeln(sum[j,r]-sum[j,l-1]);
break;
end;
end;
end;
end.