Bitset與字串
之前有過區域賽,簡化版問題:
給定一個小寫字符組成的字符串S,(|S|<1e5,下標從1開始),現在有Q種操作,對於每個操作Q(Q<=1e3),輸入opt,
如果opt==1,輸入x,c,表示把S[x]改為c,(c是小寫字母)。
如果opt==2,輸入字符串T,輸出S種有多少個字串==T(字串可以重疊),(|T|<=10)。
-------------------------------------------分界線-------------------------------------
此題:
Given a string s, process q queries, each having one of the following forms:
- 1 i c — Change the i-th character in the string to c.
- 2 l r y — Consider the substring of s starting at position l and ending at position r. Output the number of times y occurs as a substring in it.
Input
The first line of the input contains the string s
The second line contains an integer q (1 ≤ q ≤ 105) — the number of queries to process.
The next q lines describe the queries and may have one of the following forms:
- 1 i
- 2 l r y (1 ≤ l ≤ r ≤ |s|)
c is a lowercase English letter and y is a non-empty string consisting of only lowercase English letters.
The sum of |y| over all queries of second type is at most 105.
It is guaranteed that there is at least one query of second type.
All strings are 1-indexed.
|s| is the length of the string s.
Output
For each query of type 2, output the required answer in a separate line.
Example
InputababababaOutput
3
2 1 7 aba
1 5 c
2 1 7 aba
3Input
1
abcdcbcOutput
5
2 1 7 bc
1 4 b
2 4 7 bc
1 2 a
2 1 4 aa
2
2
1
Note
Consider the first sample case. Initially, the string aba occurs 3 times in the range [1, 7]. Note that two occurrences may overlap.
After the update, the string becomes ababcbaba and now aba occurs only once in the range [1, 7].
思路:題意和上面的差不多,不過數據更大一點,只有Bitset或者分塊優化(後者我沒有試過)。
具體的:1,假設我們要統計S裏有多少個T,先統計S裏面字符==T[0]的是哪些,然後統計S中有T[0]的位置後面跟的字符==T[1]的有哪些,然後統計S中有T[0]的位置後面跟的字符==T[1]的而且後面跟的字符==T[2]的有哪些.....直到對比到S[len-1]。
2,最後利用位移可以得到某個區間的1的個數。
for(i=0;i<S;i++) ans&=(bitset[T[i]-‘a‘]>>i);
ans開始全部是1; bitset是保存的T串裏每個字符的位置;
(目測還有非常高效的方法,提交列表裏有效率為5倍以上的,還有待學習)
#include<bitset> #include<cstdio> #include<cstring> #include<cstdlib> #include<iostream> #include<algorithm> using namespace std; const int maxn=100010; bitset<maxn>s[27],ans; char a[maxn],b[maxn],c[3]; void read(int &res) { char c=getchar(); while(c>‘9‘||c<‘0‘) c=getchar(); for(res=0;c>=‘0‘&&c<=‘9‘;c=getchar()) res=(res<<3)+(res<<1)+c-‘0‘; } int main() { scanf("%s",a+1); int T=strlen(a+1); int i,j,l,r,Q,opt; for(i=1;i<=T;i++) s[a[i]-‘a‘].set(i); read(Q); while(Q--){ read(opt); if(opt==1){ scanf("%d%s",&j,c); s[a[j]-‘a‘][j]=0; s[(a[j]=c[0])-‘a‘][j]=1; } else { read(l); read(r); scanf("%s",b); int S=strlen(b); if(S>r-l+1) { puts("0"); continue; } ans.set(); for(i=0;i<S;i++){ ans&=(s[b[i]-‘a‘]>>i); } printf("%d\n",(ans>>l).count()-(ans>>(r-S+2)).count()); } } return 0; }
Bitset與字串