HDU6028:Forgiveness(TLE ing,占位)
Problem Description Little Q is now checking whether string A matches B. Two strings are considered matched if they have the same length, and there are
no position i that Ai is different from Bi. However, Little Q is a kind man, he forgives every person hurt him. What's more, he even forgives strings! He gives the string 3
opportunities, if there are no more than 3 positions i that Ai is different from Bi, then Little Q will also consider the two strings
matched. For a string S, S[l,r] means the substring combined by Sl,Sl+1,...,Sr. And the function occ(A,B) returns the number of substrings
in string B which matches A. Little Q now has a long numeric 1-based string S, and his job is to deal with m operations: 1. + l r k, for every positions from l to r, change Si to (Si+k)mod10. 2. ? l r T, report occ(T,S[l,r]). After lots of work, Little Q is very tired now, please write a program to help him deal with these operations. Input The first line of the input contains an integer T(1≤T≤15), denoting the number of test cases. In each test case, there are two integers n(1≤n≤50000) and m(1≤m≤50000) in the first line, denoting the length of string S and the
number of operations. The second line of the input contains a numeric string S with n integers, each number Si is in the range of 0 to 9. In the following m lines, each line describes an operation. If it is a modification, then it is in the format of ''+ l r k'', where 1≤l≤r≤n and 1≤k≤9. If it is a query, then it is in the format of ''? l r T'', where 1≤l≤r≤n and T is a numeric string composed of integers from 0 to 9. It is guaranteed that ∑|T|≤100000 in each test case, and there are no more than 4 test cases satisfying min(n,m)>1000. Output For each query, print a single line with an integer, denoting the answer. Sample Input 1 5 5 01234 ? 2 5 1234 ? 2 5 1777 ? 2 5 9999 + 1 5 5 ? 1 5 56789 Sample Output 1 1 0 1
题意:给定字符串S,多次修改区间值,多次询问区间有多少匹配串T,可以失配3次。
超时思路:用bitset的思路去做的,每次记录T的相应位置[0,L-1]的集合,一位一位的移、求并,对于出现的失配位置,我们最多可以更新3次。假设数据小一点,没准可以过。 主要还是修改操作那里太暴力的,单点操作的题是遇到过了。
( :D, 虽然是个超时代码,但是我觉得能想出来这个不算太暴力的方法也算不错啦。以后没准能用上。
#include<bitset> #include<cstdio> #include<cstring> #include<cstdlib> #include<iostream> #include<algorithm> using namespace std; const int maxn=100010; int s[10][maxn],ans[maxn],tans[maxn]; char a[maxn],c[maxn],opt[3]; int times[maxn]; int main() { int T,N,M,L; scanf("%d",&T); while(T--){ scanf("%d%d",&N,&M); scanf("%s",a+1); int i,j,l,r,k; for(i=0;i<10;i++) for(j=0;j<=N;j++) s[i][j]=0; for(i=1;i<=N;i++) s[a[i]-'0'][i]=1; while(M--){ scanf("%s",opt); if(opt[0]=='+'){ scanf("%d%d%d",&l,&r,&k); for(i=l;i<=r;i++){ s[a[i]-'0'][j]=0; a[i]=char((a[i]-'0'+k)%10+'0'); s[a[i]-'0'][i]=1; } } else { scanf("%d%d%s",&l,&r,c); L=strlen(c); if(L>r-l+1) { puts("0"); continue; } for(i=l;i<=r;i++) times[i]=0; for(i=l;i<=r;i++) ans[i]=1;//全部为1 for(i=0;i<L;i++){ for(j=l;j<=r;j++) tans[j]=ans[j]; for(j=l;j<=r-L+1;j++) ans[j]&=s[c[i]-'0'][j+i]; for(j=l;j<=r-L+1;j++){ if(!ans[j]&&tans[j]&×[j]<3){ times[j]++; ans[j]=1; } } } int res=0; for(i=l;i<=r-L+1;i++) if(ans[i]) res++; printf("%d\n",res); } } } return 0; }
It is your time to fight!