Educational Codeforces Round 48 (Rated for Div. 2) B 1016B Segment Occurrences

題目:http://codeforces.com/problemset/problem/1016/B

題目大意:就是給兩個字符串s t,然後q次查詢,給出 [l, r], 問t出現的次數。

剛開始做這道題感覺就是瞎寫,沒有好好思考,下面給出官方的思路:首先看一下單純的做法。q次查詢,每次從 i 屬於 [l, r-m+1] 然後遍歷,看是否和t一樣。時間複雜度(q*m*n).

注意到t只能從s的n個位置開始,我們可以預處理t出現的位置,然後前綴和維護出現次數,這樣的話,每次查詢都是O(1).

AC代碼:

#include <iostream>
#include <stdio.h>
#include <math.h>
#include <string.h>
#include <stdlib.h>
#include <string>
#include <vector>
#include <set>
#include <map>
#include <queue>
#include <algorithm>
#include <sstream>
#include <stack>
using namespace std;
typedef long long ll;
const int inf = 0x3f3f3f3f;

const int N = 1000 + 7; 
int pre[N];

int main() {
	//freopen("in.txt", "r", stdin);
	int n, m, q;
	scanf("%d%d%d", &n, &m, &q);
	string s, t;
	cin >> s >> t;
	for(int i = 0; i < n - m + 1; i++) {//從s中找t開始的位置 
		bool flag = true;
		for(int j = 0; j < m; j++) {
			if(s[i + j] != t[j])
				flag = false;
		}
		pre[i+1] = pre[i] + flag;//前綴和 
	} 
	for(int i = max(0, n - m + 1); i < n; i++)//上面終止條件,n-m+1 後面的pre還沒有值 
		pre[i+1] = pre[i];
	for(int i = 0; i < q; i++) {
		int l, r;
		scanf("%d%d", &l, &r); 
		l--, r -= m - 1;//r -= m-1 變成起始位置(本次次數),l-- 變成上次出現次數
		printf("%d\n", l <= r ? pre[r] - pre[l] : 0);
	}
}


 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章