hdu 5972 Regular Number

传送门

Bitset优化。

对每一个数字开一个Bitset,若第i位为1表示第i位可以为这个数字。

再开一个Bitset ans计算答案,每次ans左移一位,ans[0]=1(ans[0]是最右边一位),然后&上串的这一位的数字对应的bitset。

到某个时候长串到了i这一位,ans中j这一位是1,表示长串的i这一位可以匹配短串的j这一位,也就是说长串i之前的可以完全匹配0~j-1位。

每一次将ans[0]置1表示短串的第0位随时都是可以开始匹配的状态。而第i位是1则需要上次,也就是左移之前这一位为1,而每次可以匹配的位置&上当前位数字的bitset,即判断这些可以匹配的位置是否匹配上了,配上了后左移让左边一位变成1,就表示它的下一位可以匹配了。

然后这道题卡常,可能是我长得不好看,把网上能找到的代码全交了一遍,全部tle,我又有什么办法呢。

//Achen
#include<algorithm>
#include<iostream>
#include<cstring>
#include<cstdlib>
#include<bitset>
#include<cstdio>
#include<vector>
#include<queue>
#include<cmath>
#define For(i,a,b) for(register int i=(a);i<=(b);i++)
#define Rep(i,a,b) for(register int i=(a);i>=(b);i--)
const int N=5e6+7;
typedef long long LL;
using namespace std;
int n;
char s[N];
bitset<1001>b[20],ans;

template<typename T> void read(T &x) {
    T f=1; x=0; char ch=getchar();
    while(ch!='-'&&(ch<'0'||ch>'9')) ch=getchar();
    if(ch=='-') f=-1,ch=getchar();
    for(;ch>='0'&&ch<='9';ch=getchar()) x=x*10+ch-'0'; x*=f;
}

int main() {
#ifdef DEBUG
    freopen("1.in","r",stdin);
    freopen("1.out","w",stdout);
#endif
    read(n);
    For(i,0,n-1) {
        int m; read(m);
        For(j,1,m) {
            int k; read(k);
            b[k].set(i);
        }
    }
    getchar();
    gets(s);
    int len=strlen(s);
    For(i,0,len-1) {
        ans<<=1;
        ans[0]=1;
        ans=(ans&b[s[i]-'0']);
        if(ans[n-1]==1) {
            char ch=s[i+1];
            s[i+1]=0;
            puts(s+i-n+1);
            s[i+1]=ch;
        }
    }
    return 0;
}
View Code

 

posted @ 2018-04-03 17:12  啊宸  阅读(172)  评论(0编辑  收藏  举报