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;
}