前綴和是一種重要的預處理,能大大降低查詢的時間複雜度。
前綴和,差分。其實可以一起學的哈哈。
文章首發
推薦這個博主寫的文章:
X丶
題目
度度熊的字符串課堂開始了!要以像度度熊一樣的天才爲目標,努力奮鬥哦!
爲了檢驗你是否具備不聽課的資質,度度熊準備了一個只包含大寫英文字母的字符串 A[1,n]=a1a2⋯an,接下來他會向你提出 q 個問題 (l,r),你需要回答字符串 A[l,r]=alal+1⋯ar 內有多少個非空子串是 A[l,r] 的所有非空子串中字典序最小的。這裏的非空子串是字符串中由至少一個位置連續的字符組成的子序列,兩個子串是不同的當且僅當這兩個子串內容不完全相同或者出現在不同的位置。
記 |S| 爲字符串 S 的長度,對於兩個字符串 S 和 T ,定義 S 的字典序比 T 小,當且僅當存在非負整數 k(≤min(|S|,|T|)) 使得 S 的前 k 個字符與 T 的前 k 個字符對應相同,並且要麼滿足 |S|=k 且 |T|>k,要麼滿足 k<min(|S|,|T|) 且 S 的第 k+1 個字符比 T 的第 k+1 個字符小。例如 “AA” 的字典序比 “AAA” 小,“AB” 的字典序比 “BA” 小。
輸入格式
第一行包含一個整數 T,表示有 T 組測試數據。
接下來依次描述 T 組測試數據。對於每組測試數據:
第一行包含兩個整數 n 和 q,表示字符串的長度以及詢問的次數。
第二行包含一個長爲 n 的只包含大寫英文字母的字符串 A[1,n]。
接下來 q 行,每行包含兩個整數 li,ri,表示第 i 次詢問的參數。
保證 1≤T≤10,1≤n,q≤105,1≤li≤ri≤n。
輸出格式
對於每組測試數據,先輸出一行信息 “Case #x:”(不含引號),其中 x 表示這是第 x 組測試數據,接下來 q 行,每行包含一個整數,表示字符串 A[l,r] 中字典序最小的子串個數,行末不要有多餘空格。
樣例輸入:
1
2 3
AB
1 1
1 2
2 2
樣例輸出:
Case #1:
1
1
1
代碼:
#include<bits/stdc++.h>
using namespace std;
int t,n,m,a,b;
int sum[30][100100];
char s[100100];
int main(){
while(scanf("%d",&t)!=EOF){
int num=1;
while(t--){
scanf("%d %d",&n,&m);
scanf("%s",s+1);
memset(sum,0,sizeof(sum));
for(int i=1;i<=n;i++){
for(int j=0;j<26;j++){
sum[j][i]=sum[j][i-1];
}
sum[s[i]-'A'][i]++;
}
printf("Case #%d:\n",num++);
while(m--){
scanf("%d %d",&a,&b);
for(int i=0;i<26;i++){
if(sum[i][b]-sum[i][a-1]!=0){
printf("%d\n",sum[i][b]-sum[i][a-1]);
break;
}
}
}
}
}
return 0;
}