nexthexonextbutterflyvolantisyearnyiliashokaindigoapollolandscapecactusmateryicarusfluidmaterial
转移自老blog

hdu5726

题目大意 :
         在母串里面找子串,字串可以变化,询问所有匹配位置
        其实是一个dp,设状态dp[i][j][0]表示母串匹配到i子串匹配到 j,且子串最后一个字符与前面的字符交换, dp[i][j][1]不交换,dp[i][j][2]交换, 于是就有了转移式子:
         dp[j][0][i] = dp[j-1][2][i-1]&&s[i]==p[j-1];
         dp[j][1][i] = (dp[j-1][1][i-1]||dp[j-1][0][i-1]) && s[i]==p[j];
         dp[j][2][i] = (dp[j-1][1][i-1]||dp[j-1][0][i-1]) && s[i]==p[j+1];
然后bitset暴力压缩掉一维,滚动数组又压缩掉一个维度。
要注意biset压缩掉大的那一维度,滚动数组压缩掉第二大的维度才能过,压反了就tle了。
#include<bits/stdc++.h>
using namespace std;

const int MAXS=1e5+5,MAXP=5e3+5;
char s[MAXS],p[MAXP];
bitset<MAXS> dp[2][3];
bitset<MAXS> s_char[26];


int main(){
    int n,m,T;
    scanf("%d",&T);
    while(T--){
        scanf("%d %d %s %s",&n,&m,s,p);
        for(int i=0;i<26;i++)s_char[i].reset();
        for(int i=0;i<n;i++)s_char[s[i]-'a'][i]=1;
        
        
        int t=1;
        
        dp[t][0][0]=0;
        dp[t][1][0]=s[0]==p[0];
        dp[t][2][0]=s[0]==p[1];
        for(int i=1;i<n;i++){
            dp[t][0][i]=0;
            dp[t][1][i]=s[i]==p[0];
            dp[t][2][i]=s[i]==p[1];
            }
        t^=1;
        
        for(int j=1;j<m;j++){
            
            dp[t][0] =  (dp[t^1][2]<<1) & s_char[p[j-1]-'a'];
            dp[t][1] = ( (dp[t^1][1]|dp[t^1][0]) << 1 ) & s_char[p[j]-'a'];
            if(j+1<m)dp[t][2] = ((dp[t^1][1]|dp[t^1][0])<<1) & s_char[p[j+1]-'a'];
            else dp[t][2].reset();
            
            dp[t][0][0] = 0;
            dp[t][1][0] = 0;
            dp[t][2][0] = 0;
            
            t^=1;
            }
        
        
        
        for(int i=m-1;i<n;i++){
            printf("%d",(dp[t^1][0][i]|dp[t^1][1][i]));
            }
        for(int i=0;i<m-1;i++){
            printf("0");
            }
        cout<<endl;
        }
    }
//000001
//0000011
<