Live2d Test Env

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]&&times[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;
}
posted @ 2018-05-02 21:53  nimphy  阅读(540)  评论(0编辑  收藏  举报