ac机 套 数位dp
写的时候错误不断 手残不断 orz
读入拒绝高精度。。。
大不了特判
打死不写高精度。。。
#include <queue>
#include <cstdio>
#define MOD 1000000009
using namespace std;
int len,n,T,con;
char s[25],c;
int u,v;
int num[805];
struct node {
bool word;
node *ch[2],*fail;
int ret,id;
}tr[200010],*root,Fail;
int cnt = -1;
queue<node*>Q;
node *NEW() {
tr[++cnt].id = cnt;
return &tr[cnt];
}
void read_str () {
len = -1;
c = getchar();
for(;c > '1' || c < '0'; c = getchar());
for(;c <= '1' && c >= '0';c = getchar())
s[++len] = c;
}
int read_int () {
char c = getchar();
int re = 0;
for(;c > '9' || c < '0';c = getchar());
for(;c <= '9' && c >= '0';c = getchar())
re = re * 10 + c - '0';
return re;
}
void build_tr () {
int ID;
node *p = root;
for(int i = 0;i <= len;++i) {
ID = s[i] - '0';
if(!p->ch[ID])
p->ch[ID] = NEW();
p = p->ch[ID];
}
p->word = 1;
}
void build_ac () {
Q.push(root);
node *p;
while(!Q.empty()) {
p = Q.front();
Q.pop();
for(int i = 0;i <= 1;++i) {
if(p->ch[i]) {
if(p == root)
p->ch[i]->fail = root;
else {
p->ch[i]->fail = p->fail->ch[i];
if(p->ch[i]->fail->word)
p->ch[i]->word = 1;
}
Q.push(p->ch[i]);
}
else {
if(p == root)
p->ch[i] = root;
else p->ch[i] = p->fail->ch[i];
}
}
}
}
int dp[805][2000];
int hash[805][2000];
node* change (node *now,int Num) {
int t = 4;
for(int i = 1;i <= 4;++i) {
if(Num >= (1 << --t)) {
Num -= 1 << t;
now = now->ch[1];
}
else now = now->ch[0];
if(now->word)
return &Fail;
}
return now;
}
int DP (int pos,bool limit,node *now,bool val) {
if(pos == num[0] + 1)
return 1;
if(hash[pos][now->id] == con && !limit && !val)
return dp[pos][now->id];
int re = 0;
node *temp;
int upp = limit ? num[pos] : 9;
for(int i = 0;i <= upp;++i) {
if(i == 0 && val) {
if(pos != num[0]) {
re += (DP(pos + 1,0,now,1) % MOD);
re %= MOD;
}
else {
re += (DP(pos + 1,0,change(now,0),1) % MOD);
re %= MOD;
}
continue;
}
temp = change(now,i);
if(temp->ret != 1) {
re += (DP(pos + 1,limit && i == upp,temp,0) % MOD);
re %= MOD;
}
}
if(!limit && hash[pos][now->id] != con && !val) {
hash[pos][now->id] = con;
dp[pos][now->id] = re;
}
return re;
}
void get_bign (bool f) {
char c = getchar();
num[0] = 0;
for(;c > '9' || c < '0';c = getchar());
for(;c <= '9' && c >= '0';c = getchar()) {
num[++num[0]] = c - '0';
}
if(f) {
int te = num[0];
--num[te];
while(num[te] == -1) {
num[te] += 10;
num[te - 1]--;
te--;
}
}
}
int main () {
Fail.ret = 1;
T = read_int();
while(T--) {
root = NEW();
n = read_int();
while(n--) {
read_str();
build_tr();
}
build_ac();
++con;
get_bign(1);
u = DP(1,1,root,1);
++con;
get_bign(0);
v = DP(1,1,root,1);
printf("%d\n",(v - u + MOD) % MOD);
}
return 0;
}