模板:

struct Ac_Automation
{
int ch[MAXNNODE][SIGMA_SIZE];
int val[MAXNNODE];
int fail[MAXNNODE],last[MAXNNODE];
bool symbol[MAXNNODE];
int sz;
Ac_Automation() {sz = ;memset(ch[],,sizeof(ch[]));symbol[] = false;}
int idx(char c)
{
return c - 'a';
} void insert(char * s)
{
int u = ,n = strlen(s);
for (int i = ; i < n ; i++)
{
int c = idx(s[i]);
if (!ch[u][c])
{
memset(ch[sz],,sizeof(ch[sz]));
symbol[sz] = false;
ch[u][c] = sz++;
}
u = ch[u][c];
}
symbol[u] = true;//最后的叶子节点给与信息v
} //建立字典树 void get_fail()
{
queue<int>q;
fail[] = ;
for (int c = ; c < SIGMA_SIZE ; c++)
{
int u = ch[][c];
if (u)
{
fail[u] = ;
q.push(u);
last[u] = ;
}
}
while (!q.empty())
{
int r = q.front();q.pop();
if (symbol[fail[r]]) symbol[r] = true;
for (int c = ; c < SIGMA_SIZE ; c++)
{
int u = ch[r][c];
if (u == )
{
ch[r][c] = ch[fail[r]][c];
continue;
}
q.push(u);
int v = fail[r];
while (v && !ch[v][c]) v = fail[v];
fail[u] = ch[v][c];
last[u] = val[fail[u]] ? fail[u] : last[fail[u]];
}
}
} void print(int j)
{
if (j)
{
// printf("%d\n",val[j]);
// cnt[val[j]]++;
print(last[j]);
}
} void Find(char * T)
{
int n = strlen(T);
int j = ;
for (int i = ; i < n ; i++)
{
int c = idx(T[i]);
// while(j && !ch[j][c]) j = f[j];
j = ch[j][c];
if (val[j]) print(j);
else if (last[j]) print(last[j]);//print是功能函数
}
} void init()
{
sz = ;
memset(ch[],,sizeof(ch[]));
symbol[] = false;
} Matrix build_mat()
{
Matrix ret = Matrix(sz + );
for (int i = ; i < sz ; i++)
for (int j = ; j < SIGMA_SIZE ; j++)
if (symbol[i] == false && !symbol[ch[i][j]])
ret.mat[i][ch[i][j]]++;
for (int i = ; i <= sz ; i++)
ret.mat[i][sz] = ;
return ret;
}
}src;

HDU 2222 Keywords Search

找出主串中有多少个模式串出现

#include <map>
#include <set>
#include <list>
#include <cmath>
#include <ctime>
#include <deque>
#include <stack>
#include <queue>
#include <cctype>
#include <cstdio>
#include <string>
#include <vector>
#include <climits>
#include <cstdlib>
#include <cstring>
#include <iostream>
#include <algorithm>
#define LL long long
#define PI 3.1415926535897932626
using namespace std;
int gcd(int a, int b) {return a % b == ? b : gcd(b, a % b);}
int ans;
const int MAXNNODE = ;
const int SIGMA_SIZE = ;
struct Ac_Automation
{
int ch[MAXNNODE][SIGMA_SIZE];
int val[MAXNNODE];
int cnt[MAXNNODE];
int sz;
Ac_Automation() {sz = ;memset(ch[],,sizeof(ch[]));}
int idx(char c) {return c - 'a';} void insert(char * s,int v)
{
int u = ,n = strlen(s);
for (int i = ; i < n ; i++)
{
int c = idx(s[i]);
if (!ch[u][c])
{
memset(ch[sz],,sizeof(ch[sz]));
val[sz] = ;
ch[u][c] = sz++;
}
u = ch[u][c];
}
cnt[u]++;
val[u] = v;//最后的叶子节点给与信息v
} //建立字典树 int fail[MAXNNODE],last[MAXNNODE];
int get_fail()
{
queue<int>q;
fail[] = ;
for (int c = ; c < SIGMA_SIZE ; c++)
{
int u = ch[][c];
if (u)
{
fail[u] = ;
q.push(u);
last[u] = ;
}
}
while (!q.empty())
{
int r = q.front();q.pop();
for (int c = ; c < SIGMA_SIZE ; c++)
{
int u = ch[r][c];
if (u == )
{
ch[r][c] = ch[fail[r]][c];
continue;
}
q.push(u);
int v = fail[r];
while (v && !ch[v][c]) v = fail[v];
fail[u] = ch[v][c];
last[u] = val[fail[u]] ? fail[u] : last[fail[u]];
}
}
} void print(int j)
{
if (j)
{
ans += cnt[j];
cnt[j] = ;
print(last[j]);
}
} void Find(char * T)
{
int n = strlen(T);
int j = ;
for (int i = ; i < n ; i++)
{
int c = idx(T[i]);
// while(j && !ch[j][c]) j = f[j];
j = ch[j][c];
if (val[j]) print(j);
else if (last[j]) print(last[j]);//print是功能函数
}
} void init()
{
sz = ;
memset(ch[],,sizeof(ch[]));
memset(cnt,false,sizeof(cnt));
}
}src;
int N;
char input[];
char tag[];
int main()
{
//freopen("sample.txt","r",stdin);
int T;
scanf("%d",&T);
while (T--)
{
scanf("%d",&N);
gets(input);
src.init();
ans = ;
for (int i = ; i < N; i++)
{
gets(input);
src.insert(input,i + );
}
scanf("%s",tag);
src.get_fail();
src.Find(tag);
printf("%d\n",ans);
}
return ;
}

HDU 2896 病毒侵袭

#include <map>
#include <set>
#include <list>
#include <cmath>
#include <ctime>
#include <deque>
#include <stack>
#include <queue>
#include <cctype>
#include <cstdio>
#include <string>
#include <vector>
#include <climits>
#include <cstdlib>
#include <cstring>
#include <iostream>
#include <algorithm>
#define LL long long
#define PI 3.1415926535897932626
using namespace std;
int gcd(int a, int b) {return a % b == ? b : gcd(b, a % b);}
const int MAXNNODE = ;
const int SIGMA_SIZE = ;
vector<int>ans;
struct Ac_Automation
{
int ch[MAXNNODE][SIGMA_SIZE];
int val[MAXNNODE];
int sz;
Ac_Automation() {sz = ;memset(ch[],,sizeof(ch[]));}
int idx(char c) {return c;} void insert(char * s,int v)
{
int u = ,n = strlen(s);
for (int i = ; i < n ; i++)
{
int c = idx(s[i]);
if (!ch[u][c])
{
memset(ch[sz],,sizeof(ch[sz]));
val[sz] = ;
ch[u][c] = sz++;
}
u = ch[u][c];
} val[u] = v;//最后的叶子节点给与信息v
} //建立字典树 int fail[MAXNNODE],last[MAXNNODE];
void get_fail()
{
queue<int>q;
fail[] = ;
for (int c = ; c < SIGMA_SIZE ; c++)
{
int u = ch[][c];
if (u)
{
fail[u] = ;
q.push(u);
last[u] = ;
}
}
while (!q.empty())
{
int r = q.front();q.pop();
for (int c = ; c < SIGMA_SIZE ; c++)
{
int u = ch[r][c];
if (u == )
{
ch[r][c] = ch[fail[r]][c];
continue;
}
q.push(u);
int v = fail[r];
while (v && !ch[v][c]) v = fail[v];
fail[u] = ch[v][c];
last[u] = val[fail[u]] ? fail[u] : last[fail[u]];
}
}
} void print(int j)
{
if (j)
{
ans.push_back(val[j]);
print(last[j]);
}
} void Find(char * T)
{
int n = strlen(T);
int j = ;
for (int i = ; i < n ; i++)
{
int c = idx(T[i]);
// while(j && !ch[j][c]) j = f[j];
j = ch[j][c];
if (val[j]) print(j);
else if (last[j]) print(last[j]);//print是功能函数
}
} void init()
{
sz = ;
memset(ch[],,sizeof(ch[]));
//memset(cnt,false,sizeof(cnt));
}
}src;
char tmp[];
int N,M;
char tag[];
int main()
{
//freopen("sample.txt","r",stdin);
while (scanf("%d",&N) != EOF)
{
src.init();
for (int i = ; i <= N; i++)
{
scanf("%s",tmp);
src.insert(tmp,i);
}
src.get_fail();
scanf("%d",&M);
int ret = ;
for (int i = ; i <= M; i++)
{
ans.clear();
scanf("%s",tag);
src.Find(tag);
if (ans.size() == ) continue;
ret++;
printf("web %d:",i);
sort(ans.begin(),ans.end());
int k = unique(ans.begin(),ans.end()) - ans.begin();
for (int i = ; i < k ; i++)
printf(" %d",ans[i]);
putchar('\n');
}
printf("total: %d\n",ret);
}
return ;
}

HDU 3065 病毒侵袭持续中

#include <map>
#include <set>
#include <list>
#include <cmath>
#include <ctime>
#include <deque>
#include <stack>
#include <queue>
#include <cctype>
#include <cstdio>
#include <string>
#include <vector>
#include <climits>
#include <cstdlib>
#include <cstring>
#include <iostream>
#include <algorithm>
#define LL long long
#define PI 3.1415926535897932626
using namespace std;
int gcd(int a, int b) {return a % b == ? b : gcd(b, a % b);}
const int MAXNNODE = ;
const int SIGMA_SIZE = ;
int cnt[MAXNNODE];
struct Ac_Automation
{
int ch[MAXNNODE][SIGMA_SIZE];
int val[MAXNNODE];
int fail[MAXNNODE],last[MAXNNODE];
int sz;
Ac_Automation() {sz = ;memset(ch[],,sizeof(ch[]));}
int idx(char c) {return c - 'A';} void insert(char * s,int v)
{
int u = ,n = strlen(s);
for (int i = ; i < n ; i++)
{
int c = idx(s[i]);
if (!ch[u][c])
{
memset(ch[sz],,sizeof(ch[sz]));
val[sz] = ;
ch[u][c] = sz++;
}
u = ch[u][c];
}
val[u] = v;//最后的叶子节点给与信息v
} //建立字典树 void get_fail()
{
queue<int>q;
fail[] = ;
for (int c = ; c < SIGMA_SIZE ; c++)
{
int u = ch[][c];
if (u)
{
fail[u] = ;
q.push(u);
last[u] = ;
}
}
while (!q.empty())
{
int r = q.front();q.pop();
for (int c = ; c < SIGMA_SIZE ; c++)
{
int u = ch[r][c];
if (u == )
{
ch[r][c] = ch[fail[r]][c];
continue;
}
q.push(u);
int v = fail[r];
while (v && !ch[v][c]) v = fail[v];
fail[u] = ch[v][c];
last[u] = val[fail[u]] ? fail[u] : last[fail[u]];
}
}
} void print(int j)
{
if (j)
{
// printf("%d\n",val[j]);
cnt[val[j]]++;
print(last[j]);
}
} void Find(char * T)
{
int n = strlen(T);
int j = ;
for (int i = ; i < n ; i++)
{
int c = idx(T[i]);
// while(j && !ch[j][c]) j = f[j];
j = ch[j][c];
if (val[j]) print(j);
else if (last[j]) print(last[j]);//print是功能函数
}
} void init()
{
sz = ;
memset(ch[],,sizeof(ch[]));
}
}src;
char input[][];
char word[];
int N;
int main()
{
while (scanf("%d",&N) != EOF)
{
memset(cnt,,sizeof(cnt));
src.init();
for (int i = ; i <= N ; i++)
{
scanf("%s",input[i]);
src.insert(input[i],i);
}
src.get_fail();
scanf("%s",word);
src.Find(word);
for (int i = ; i <= N ; i++)
{
if (cnt[i])
printf("%s: %d\n",input[i],cnt[i]);
}
}
return ;
}

ZOJ 3430 Detect the Virus

题意:给出n个编码后的模板串,然后有M次询问,每次询问输入一个编码后的文本串,问在编码前,有多少个模板串在文本串中出现过。

#include <map>
#include <set>
#include <list>
#include <cmath>
#include <ctime>
#include <deque>
#include <stack>
#include <queue>
#include <cctype>
#include <cstdio>
#include <string>
#include <vector>
#include <climits>
#include <cstdlib>
#include <cstring>
#include <iostream>
#include <algorithm>
#define LL long long
#define PI 3.1415926535897932626
using namespace std;
int gcd(int a, int b) {return a % b == ? b : gcd(b, a % b);}
const int SIGMA_SIZE = ;
const int MAXNNODE = ;
vector<int>ret;
struct Ac_Automation
{
int ch[MAXNNODE][SIGMA_SIZE];
int val[MAXNNODE];
int fail[MAXNNODE],last[MAXNNODE];
int sz;
Ac_Automation() {sz = ;memset(ch[],,sizeof(ch[]));}
// int idx(char c) {return c;} void insert(int * s,int n,int v)
{
int u = ;
for (int i = ; i < n ; i++)
{
int c = s[i];
if (!ch[u][c])
{
memset(ch[sz],,sizeof(ch[sz]));
val[sz] = ;
ch[u][c] = sz++;
}
u = ch[u][c];
}
val[u] = v;//最后的叶子节点给与信息v
} //建立字典树 void get_fail()
{
queue<int>q;
fail[] = ;
for (int c = ; c < SIGMA_SIZE ; c++)
{
int u = ch[][c];
if (u)
{
fail[u] = ;
q.push(u);
last[u] = ;
}
}
while (!q.empty())
{
int r = q.front();q.pop();
for (int c = ; c < SIGMA_SIZE ; c++)
{
int u = ch[r][c];
if (u == )
{
ch[r][c] = ch[fail[r]][c];
continue;
}
q.push(u);
int v = fail[r];
while (v && !ch[v][c]) v = fail[v];
fail[u] = ch[v][c];
last[u] = val[fail[u]] ? fail[u] : last[fail[u]];
}
}
} void print(int j)
{
if (j)
{
// printf("%d\n",val[j]);
ret.push_back(val[j]);
print(last[j]);
}
} void Find(int * T,int n)
{
int j = ;
for (int i = ; i < n ; i++)
{
int c = T[i];
// while(j && !ch[j][c]) j = f[j];
j = ch[j][c];
if (val[j]) print(j);
else if (last[j]) print(last[j]);//print是功能函数
}
} void init()
{
sz = ;
memset(ch[],,sizeof(ch[]));
}
}src; int getid(char ch) {
if (isupper(ch)) return ch - 'A';
if (islower(ch)) return ch - 'a' + ;
if (isdigit(ch)) return ch - '' + ;
if (ch == '+') return ;
return ;
} int str[];
char word[];
int bit[ * ];
int decode(char * s) {
int top = ,res[];
int len = strlen(s);
for (int i = ; i < len ; i++) {
if (s[i] != '=') {
int idx = getid(s[i]);
for (int j = ; j >= ; j--) {
res[j] = idx & ;
idx >>= ;
}
for (int j = ; j < ; j++) {
bit[top++] = res[j];
}
}
else top -= ;
}
int x = ,tot = ;
for (int i = ; i < top ;) {
x = ;
for (int j = ; j < ; j++)
x = x * + bit[i++];
str[tot++] = x;
}
return tot;
} int main() {
int N,M;
while (scanf("%d",&N) != EOF) {
src.init();
for (int i = ; i <= N ; i++) {
scanf("%s",word);
int length = decode(word);
src.insert(str,length,i);
}
src.get_fail();
scanf("%d",&M);
while (M--) {
ret.clear();
scanf("%s",word);
int length = decode(word);
src.Find(str,length);
sort(ret.begin(),ret.end());
int cnt = unique(ret.begin(),ret.end()) - ret.begin();
printf("%d\n",cnt);
}
puts("");
}
return ;
}

POJ 2778 DNA Sequence

题意:有m种DNA序列是有疾病的,问有多少种长度为n的DNA序列不包含任何一种有疾病的DNA序列。(仅含A,T,C,G四个字符)

复制一下别人的题解

这个和矩阵有什么关系呢???
•上图是例子{“ACG”,”C”},构建trie图后如图所示,从每个结点出发都有4条边(A,T,C,G)
•从状态0出发走一步有4种走法:
  –走A到状态1(安全);
  –走C到状态4(危险);
  –走T到状态0(安全);
  –走G到状态0(安全);
•所以当n=1时,答案就是3
•当n=2时,就是从状态0出发走2步,就形成一个长度为2的字符串,只要路径上没有经过危险结点,有几种走法,那么答案就是几种。依此类推走n步就形成长度为n的字符串。
•建立trie图的邻接矩阵M:

2 1 0 0 1

2 1 1 0 0

1 1 0 1 1

2 1 0 0 1

2 1 0 0 1

M[i,j]表示从结点i到j只走一步有几种走法。

那么M的n次幂就表示从结点i到j走n步有几种走法。

注意:危险结点要去掉,也就是去掉危险结点的行和列。结点3和4是单词结尾所以危险,结点2的fail指针指向4,当匹配”AC”时也就匹配了”C”,所以2也是危险的。

矩阵变成M:

2 1

2 1

计算M[][]的n次幂,然后 Σ(M[0,i]) mod 100000 就是答案。

由于n很大,可以使用二分来计算矩阵的幂

#include <map>
#include <set>
#include <list>
#include <cmath>
#include <ctime>
#include <deque>
#include <stack>
#include <queue>
#include <cctype>
#include <cstdio>
#include <string>
#include <vector>
#include <climits>
#include <cstdlib>
#include <cstring>
#include <iostream>
#include <algorithm>
#define LL long long
#define PI 3.1415926535897932626
using namespace std;
int gcd(int a, int b) {return a % b == ? b : gcd(b, a % b);}
const int MAXNNODE = ;
const int SIGMA_SIZE = ;
const LL MOD = ;
struct Matrix {
LL mat[MAXNNODE][MAXNNODE];
int n;
Matrix(){}
Matrix(int sz) {
n = sz;
for (int i = ; i < n ; i++)
for (int j = ; j < n ; j++) mat[i][j] = ;
} Matrix operator * (const Matrix &b) const{
Matrix ret = Matrix(n);
for (int i = ; i < n ; i++)
for (int j = ; j < n ; j++)
for (int k = ; k < n ; k++)
ret.mat[i][j] = (ret.mat[i][j] + mat[i][k] * b.mat[k][j]) % MOD;
return ret;
}
}; LL pow_mod(LL x,int cnt) {
LL ret = ;
while (cnt) {
if (cnt & ) ret = ret * x;
x = x * x % MOD;
cnt >>= ;
}
return ret;
} Matrix mat_pow(Matrix in,LL cnt) {
Matrix ret = Matrix(in.n);
Matrix x = in;
for (int i = ; i < ret.n ; i++) ret.mat[i][i] = ;
while (cnt) {
if (cnt & 1LL) ret = ret * x;
x = x * x;
cnt >>= 1LL;
}
return ret;
} struct Ac_Automation
{
int ch[MAXNNODE][SIGMA_SIZE];
int val[MAXNNODE];
int fail[MAXNNODE],last[MAXNNODE];
bool symbol[MAXNNODE];
int sz;
Ac_Automation() {sz = ;memset(ch[],,sizeof(ch[]));symbol[] = false;}
int idx(char c)
{
if (c == 'A') return ;
if (c == 'T') return ;
if (c == 'C') return ;
return ;
} void insert(char * s)
{
int u = ,n = strlen(s);
for (int i = ; i < n ; i++)
{
int c = idx(s[i]);
if (!ch[u][c])
{
memset(ch[sz],,sizeof(ch[sz]));
symbol[sz] = false;
ch[u][c] = sz++;
}
u = ch[u][c];
}
symbol[u] = true;//最后的叶子节点给与信息v
} //建立字典树 void get_fail()
{
queue<int>q;
fail[] = ;
for (int c = ; c < SIGMA_SIZE ; c++)
{
int u = ch[][c];
if (u)
{
fail[u] = ;
q.push(u);
last[u] = ;
}
}
while (!q.empty())
{
int r = q.front();q.pop();
if (symbol[fail[r]]) symbol[r] = true;
for (int c = ; c < SIGMA_SIZE ; c++)
{
int u = ch[r][c];
if (u == )
{
ch[r][c] = ch[fail[r]][c];
continue;
}
q.push(u);
int v = fail[r];
while (v && !ch[v][c]) v = fail[v];
fail[u] = ch[v][c];
last[u] = val[fail[u]] ? fail[u] : last[fail[u]];
}
}
} void print(int j)
{
if (j)
{
// printf("%d\n",val[j]);
// cnt[val[j]]++;
print(last[j]);
}
} void Find(char * T)
{
int n = strlen(T);
int j = ;
for (int i = ; i < n ; i++)
{
int c = idx(T[i]);
// while(j && !ch[j][c]) j = f[j];
j = ch[j][c];
if (val[j]) print(j);
else if (last[j]) print(last[j]);//print是功能函数
}
} void init()
{
sz = ;
memset(ch[],,sizeof(ch[]));
symbol[] = false;
} Matrix build_mat()
{
Matrix ret = Matrix(sz);
for (int i = ; i < sz ; i++)
for (int j = ; j < SIGMA_SIZE ; j++)
if (symbol[i] == false && !symbol[ch[i][j]])
ret.mat[i][ch[i][j]]++;
return ret;
}
}src; int main() {
LL M,N;
char tmp[];
while (scanf("%I64d%I64d",&M,&N) != EOF) {
src.init();
for (int i = ; i < M ; i++) {
scanf("%s",tmp);
src.insert(tmp);
}
src.get_fail();
Matrix cur = src.build_mat();
/* for (int i = 0 ; i < cur.n ; i++){
for (int j = 0 ; j < cur.n ; j++)
printf("%I64d ",cur.mat[i][j]);
puts("");
}*/
// Matrix ret = cur * cur * cur;
Matrix ret = mat_pow(cur,N);
/* for (int i = 0 ; i < cur.n ; i++){
for (int j = 0 ; j < cur.n ; j++)
printf("%I64d ",ret.mat[i][j]);
puts("");
}*/
LL ans = ;
for (int i = ; i < src.sz ; i++)
ans = (ans + ret.mat[][i]) % MOD;
printf("%I64d\n",ans);
}
return ;
}

HDU 2243 考研路茫茫――单词情结

这题的意思是,给你n个长度不超过5的字符串,求有多少个长度为至少为L的字符串,里面至少包含n个字符串中的一个。

这题和求DNA片段的差不多啦,只不过L的条件有点变化。

POJ2778 是求长度为n,不包含模式串。

假设矩阵A里储存着字符间的可行转移,那么A^L就代表了长度为L的不包含n个字符串中任何一个的个数。

最终的答案就是26^1+26^2+......+26^L减去A^1+A^2+....+A^L

矩阵A可以用ac自动机维护一个跳转表得到。接下来就是考虑如何快速的求得A^1+A^2+....+A^L了。

根据矩阵的性质

|A  ,  1|                 |A^n , 1+A^1+A^2+....+A^(n-1)|

|0  ,  1| 的n次方等于|0     ,                                       1|

利用POJ 2778 的方式构建A

#include <map>
#include <set>
#include <list>
#include <cmath>
#include <ctime>
#include <deque>
#include <stack>
#include <queue>
#include <cctype>
#include <cstdio>
#include <string>
#include <vector>
#include <climits>
#include <cstdlib>
#include <cstring>
#include <iostream>
#include <algorithm>
#define ULL unsigned long long
#define LL unsigned long long
#define PI 3.1415926535897932626
using namespace std;
int gcd(int a, int b) {return a % b == ? b : gcd(b, a % b);}
const int MAXNNODE = ;
const int SIGMA_SIZE = ;
const LL MOD = ;
struct Matrix {
ULL mat[MAXNNODE][MAXNNODE];
int n;
Matrix(){}
Matrix(int sz) {
n = sz;
for (int i = ; i < n ; i++)
for (int j = ; j < n ; j++) mat[i][j] = ;
} Matrix operator * (const Matrix &b) const{
Matrix ret = Matrix(n);
for (int i = ; i < n ; i++)
for (int j = ; j < n ; j++)
for (int k = ; k < n ; k++)
ret.mat[i][j] = (ret.mat[i][j] + mat[i][k] * b.mat[k][j]);
return ret;
}
}; LL pow_mod(LL x,int cnt) {
LL ret = ;
while (cnt) {
if (cnt & ) ret = ret * x;
x = x * x % MOD;
cnt >>= ;
}
return ret;
} Matrix mat_pow(Matrix in,LL cnt) {
Matrix ret = Matrix(in.n);
Matrix x = in;
for (int i = ; i < ret.n ; i++) ret.mat[i][i] = ;
while (cnt) {
if (cnt & 1LL) ret = ret * x;
x = x * x;
cnt >>= 1LL;
}
return ret;
} struct Ac_Automation
{
int ch[MAXNNODE][SIGMA_SIZE];
int val[MAXNNODE];
int fail[MAXNNODE],last[MAXNNODE];
bool symbol[MAXNNODE];
int sz;
Ac_Automation() {sz = ;memset(ch[],,sizeof(ch[]));symbol[] = false;}
int idx(char c)
{
return c - 'a';
} void insert(char * s)
{
int u = ,n = strlen(s);
for (int i = ; i < n ; i++)
{
int c = idx(s[i]);
if (!ch[u][c])
{
memset(ch[sz],,sizeof(ch[sz]));
symbol[sz] = false;
ch[u][c] = sz++;
}
u = ch[u][c];
}
symbol[u] = true;//最后的叶子节点给与信息v
} //建立字典树 void get_fail()
{
queue<int>q;
fail[] = ;
for (int c = ; c < SIGMA_SIZE ; c++)
{
int u = ch[][c];
if (u)
{
fail[u] = ;
q.push(u);
last[u] = ;
}
}
while (!q.empty())
{
int r = q.front();q.pop();
if (symbol[fail[r]]) symbol[r] = true;
for (int c = ; c < SIGMA_SIZE ; c++)
{
int u = ch[r][c];
if (u == )
{
ch[r][c] = ch[fail[r]][c];
continue;
}
q.push(u);
int v = fail[r];
while (v && !ch[v][c]) v = fail[v];
fail[u] = ch[v][c];
last[u] = val[fail[u]] ? fail[u] : last[fail[u]];
}
}
} void print(int j)
{
if (j)
{
// printf("%d\n",val[j]);
// cnt[val[j]]++;
print(last[j]);
}
} void Find(char * T)
{
int n = strlen(T);
int j = ;
for (int i = ; i < n ; i++)
{
int c = idx(T[i]);
// while(j && !ch[j][c]) j = f[j];
j = ch[j][c];
if (val[j]) print(j);
else if (last[j]) print(last[j]);//print是功能函数
}
} void init()
{
sz = ;
memset(ch[],,sizeof(ch[]));
symbol[] = false;
} Matrix build_mat()
{
Matrix ret = Matrix(sz + );
for (int i = ; i < sz ; i++)
for (int j = ; j < SIGMA_SIZE ; j++)
if (symbol[i] == false && !symbol[ch[i][j]])
ret.mat[i][ch[i][j]]++;
for (int i = ; i <= sz ; i++)
ret.mat[i][sz] = ;
return ret;
}
}src; int main() {
LL M,N;
char tmp[];
while (scanf("%I64d%I64d",&M,&N) != EOF) {
src.init();
for (int i = ; i < M ; i++) {
scanf("%s",tmp);
src.insert(tmp);
}
src.get_fail();
Matrix cur = src.build_mat();
/* for (int i = 0 ; i < cur.n ; i++){
for (int j = 0 ; j < cur.n ; j++)
printf("%I64d ",cur.mat[i][j]);
puts("");
}*/
// Matrix ret = cur * cur * cur;
Matrix ret = mat_pow(cur,N);
/* for (int i = 0 ; i < cur.n ; i++){
for (int j = 0 ; j < cur.n ; j++)
printf("%I64d ",ret.mat[i][j]);
puts("");
}*/
ULL ans = ;
for (int i = ; i <= src.sz ; i++)
ans = (ans + ret.mat[][i]);
ans--; Matrix t = Matrix();
t.mat[][] = ;
t.mat[][] = t.mat[][] = ;
t = mat_pow(t,N);
ULL res = t.mat[][] + t.mat[][];
// << res << endl;
res--;
printf("%I64u\n",res - ans);
}
return ;
}

POJ 1625 Censored!

题意:给出包含n个可见字符的字符集,以下所提字符串均由该字符集中的字符构成。给出p个长度不超过10的字符串,求长为m且不包含上述p个字符串的字符串有多少个。

#include <map>
#include <set>
#include <list>
#include <cmath>
#include <ctime>
#include <deque>
#include <stack>
#include <queue>
#include <cctype>
#include <cstdio>
#include <string>
#include <vector>
#include <climits>
#include <cstdlib>
#include <cstring>
#include <iostream>
#include <algorithm>
#define LL long long
#define PI 3.1415926535897932626
using namespace std;
int gcd(int a, int b) {return a % b == ? b : gcd(b, a % b);}
map<char,int>mp;
struct Matrix
{
int mat[][];
int n;
Matrix(){}
Matrix(int sz)
{
n = sz;
for (int i = ; i < n ; i++)
for (int j = ; j < n ; j++) mat[i][j] = ;
}
}mt; const int numlen = ;
const int MAXNNODE = * ;
const int SIGMA_SIZE = ;
int N,M,P,cas;
struct bign {
int len, s[numlen];
bign() {
memset(s, , sizeof(s));
len = ;
}
bign(int num) { *this = num; }
bign(const char *num) { *this = num; }
bign operator = (const int num) {
char s[numlen];
sprintf(s, "%d", num);
*this = s;
return *this;
}
bign operator = (const char *num) {
len = strlen(num);
while(len > && num[] == '') num++, len--;
for(int i = ;i < len; i++) s[i] = num[len-i-] - '';
return *this;
} void deal() {
while(len > && !s[len-]) len--;
} bign operator + (const bign &a) const {
bign ret;
ret.len = ;
int top = max(len, a.len) , add = ;
for(int i = ;add || i < top; i++) {
int now = add;
if(i < len) now += s[i];
if(i < a.len) now += a.s[i];
ret.s[ret.len++] = now%;
add = now/;
}
return ret;
}
bign operator - (const bign &a) const {
bign ret;
ret.len = ;
int cal = ;
for(int i = ;i < len; i++) {
int now = s[i] - cal;
if(i < a.len) now -= a.s[i];
if(now >= ) cal = ;
else {
cal = ; now += ;
}
ret.s[ret.len++] = now;
}
ret.deal();
return ret;
}
bign operator * (const bign &a) const {
bign ret;
ret.len = len + a.len;
for(int i = ;i < len; i++) {
for(int j = ;j < a.len; j++)
ret.s[i+j] += s[i]*a.s[j];
}
for(int i = ;i < ret.len; i++) {
ret.s[i+] += ret.s[i]/;
ret.s[i] %= ;
}
ret.deal();
return ret;
} bign operator * (const int num) {
// printf("num = %d\n", num);
bign ret;
ret.len = ;
int bb = ;
for(int i = ;i < len; i++) {
int now = bb + s[i]*num;
ret.s[ret.len++] = now%;
bb = now/;
}
while(bb) {
ret.s[ret.len++] = bb % ;
bb /= ;
}
ret.deal();
return ret;
} bign operator / (const bign &a) const {
bign ret, cur = ;
ret.len = len;
for(int i = len-;i >= ; i--) {
cur = cur*;
cur.s[] = s[i];
while(cur >= a) {
cur -= a;
ret.s[i]++;
}
}
ret.deal();
return ret;
} bign operator % (const bign &a) const {
bign b = *this / a;
return *this - b*a;
} bign operator += (const bign &a) { *this = *this + a; return *this; }
bign operator -= (const bign &a) { *this = *this - a; return *this; }
bign operator *= (const bign &a) { *this = *this * a; return *this; }
bign operator /= (const bign &a) { *this = *this / a; return *this; }
bign operator %= (const bign &a) { *this = *this % a; return *this; } bool operator < (const bign &a) const {
if(len != a.len) return len < a.len;
for(int i = len-;i >= ; i--) if(s[i] != a.s[i])
return s[i] < a.s[i];
return false;
}
bool operator > (const bign &a) const { return a < *this; }
bool operator <= (const bign &a) const { return !(*this > a); }
bool operator >= (const bign &a) const { return !(*this < a); }
bool operator == (const bign &a) const { return !(*this > a || *this < a); }
bool operator != (const bign &a) const { return *this > a || *this < a; } string str() const {
string ret = "";
for(int i = ;i < len; i++) ret = char(s[i] + '') + ret;
return ret;
}
};
istream& operator >> (istream &in, bign &x) {
string s;
in >> s;
x = s.c_str();
return in;
}
ostream& operator << (ostream &out, const bign &x) {
out << x.str();
return out;
} bign dp[][]; struct Ac_Automation
{
int ch[MAXNNODE][SIGMA_SIZE];
int val[MAXNNODE];
int fail[MAXNNODE],last[MAXNNODE];
int sz;
Ac_Automation() {sz = ;memset(ch[],,sizeof(ch[]));}
int idx(char c) {return mp[c];} void insert(char * s,int v)
{
int u = ,n = strlen(s);
for (int i = ; i < n ; i++)
{
int c = idx(s[i]);
if (!ch[u][c])
{
memset(ch[sz],,sizeof(ch[sz]));
val[sz] = ;
ch[u][c] = sz++;
}
u = ch[u][c];
}
val[u] = v;//最后的叶子节点给与信息v
} //建立字典树 void get_fail()
{
queue<int>q;
fail[] = ;
for (int c = ; c < SIGMA_SIZE ; c++)
{
int u = ch[][c];
if (u)
{
fail[u] = ;
q.push(u);
last[u] = ;
}
}
while (!q.empty())
{
int r = q.front();q.pop();
val[r] |= val[fail[r]];
for (int c = ; c < SIGMA_SIZE ; c++)
{
int u = ch[r][c];
if (u == )
{
ch[r][c] = ch[fail[r]][c];
continue;
}
q.push(u);
int v = fail[r];
while (v && !ch[v][c]) v = fail[v];
fail[u] = ch[v][c];
last[u] = val[fail[u]] ? fail[u] : last[fail[u]];
}
}
} void print(int j)
{
if (j)
{
// printf("%d\n",val[j]);
//cnt[val[j]]++;
print(last[j]);
}
} void Find(char * T)
{
int n = strlen(T);
int j = ;
for (int i = ; i < n ; i++)
{
int c = idx(T[i]);
// while(j && !ch[j][c]) j = f[j];
j = ch[j][c];
if (val[j]) print(j);
else if (last[j]) print(last[j]);//print是功能函数
}
} void init()
{
sz = ;
memset(ch[],,sizeof(ch[]));
} Matrix build_mat()
{
Matrix ret = Matrix(sz);
for (int i = ; i < sz ; i++)
{
for (int j = ; j < N ; j++)
if (val[ch[i][j]] == false)
ret.mat[i][ch[i][j]]++;
}
return ret;
} void slove()
{
int cur = ;
dp[cur][] = ;
for (int i = ; i < sz ; i++)
dp[cur][i] = ;
for (int i = ; i < M ; i++)
{
cur ^= ;
for (int j = ; j < sz ; j++) dp[cur][j] = ;
for (int j = ; j < sz ; j++)
{
for (int k = ; k < sz ; k++)
if (mt.mat[j][k] > )
dp[cur][k] = dp[cur][k] + dp[cur ^ ][j] * mt.mat[j][k];
}
}
bign ret = "";
for (int i = ; i < sz ; i++)
ret = ret + dp[cur][i];
cout << ret << endl;
}
}src;
char str[];
int main()
{
// freopen("sample.txt","r",stdin);
while (scanf("%d%d%d",&N,&M,&P) != EOF)
{
mp.clear();
gets(str);
cas = ;
gets(str);
int len = strlen(str);
for (int i = ; i < len ; i++)
mp[str[i]] = cas++;
src.init();
for (int i = ; i < P; i++)
{
gets(str);
src.insert(str,);
}
src.get_fail();
mt = src.build_mat();
src.slove();
}
return ;
}

HDU 2825 Wireless Password

#include <map>
#include <set>
#include <list>
#include <cmath>
#include <ctime>
#include <deque>
#include <stack>
#include <queue>
#include <cctype>
#include <cstdio>
#include <string>
#include <vector>
#include <climits>
#include <cstdlib>
#include <cstring>
#include <iostream>
#include <algorithm>
#define LL long long
#define PI 3.1415926535897932626
using namespace std;
int gcd(int a, int b) {return a % b == ? b : gcd(b, a % b);}
const int MAXNNODE = ;
const int SIGMA_SIZE = ;
const int MOD = ;
int N,M,K;
struct Ac_Automation
{
int ch[MAXNNODE][SIGMA_SIZE];
int val[MAXNNODE];
int dp[][MAXNNODE][ << ];
int sz;
Ac_Automation() {sz = ;memset(ch[],,sizeof(ch[]));}
int idx(char c) {return c - 'a';} void insert(char * s,int v)
{
int u = ,n = strlen(s);
for (int i = ; i < n ; i++)
{
int c = idx(s[i]);
if (!ch[u][c])
{
memset(ch[sz],,sizeof(ch[sz]));
val[sz] = ;
ch[u][c] = sz++;
}
u = ch[u][c];
}
val[u] = v;//最后的叶子节点给与信息v
} //建立字典树 int fail[MAXNNODE],last[MAXNNODE];
void get_fail()
{
queue<int>q;
fail[] = ;
for (int c = ; c < SIGMA_SIZE ; c++)
{
int u = ch[][c];
if (u)
{
fail[u] = ;
q.push(u);
last[u] = ;
}
}
while (!q.empty())
{
int r = q.front();q.pop();
val[r] |= val[fail[r]];
for (int c = ; c < SIGMA_SIZE ; c++)
{
int u = ch[r][c];
if (u == )
{
ch[r][c] = ch[fail[r]][c];
continue;
}
q.push(u);
int v = fail[r];
while (v && !ch[v][c]) v = fail[v];
fail[u] = ch[v][c];
last[u] = val[fail[u]] ? fail[u] : last[fail[u]];
// val[u] |= val[fail[u]];
}
}
} void print(int j)
{
if (j)
{ print(last[j]);
}
} void Find(char * T)
{
int n = strlen(T);
int j = ;
for (int i = ; i < n ; i++)
{
int c = idx(T[i]);
// while(j && !ch[j][c]) j = f[j];
j = ch[j][c];
if (val[j]) print(j);
else if (last[j]) print(last[j]);//print是功能函数
}
} void init()
{
sz = ;
memset(ch[],,sizeof(ch[]));
// memset(cnt,false,sizeof(cnt));
} int calcu(int n,int sta,int num)
{
memset(dp[],,sizeof(dp[]));
int cur = ,nxt;
dp[][][] = ;
while (n--)
{
nxt = - cur;
memset(dp[nxt],,sizeof(dp[nxt]));
for (int i = ; i < sz ; i++)
for (int j = ; j < sta ; j++)
{
if (dp[cur][i][j] == ) continue;
for (int k = ; k < SIGMA_SIZE ; k++)
{
int tmp = ch[i][k];
int nextsta = (j | (val[tmp]));
dp[nxt][tmp][nextsta] = (dp[nxt][tmp][nextsta] + dp[cur][i][j]) % MOD;
}
}
cur = nxt;
}
int ret = ;
for (int j = ; j < sta ; j++)
{
int cnt = ;
for (int i = ; i < N; i++)
if (j & ( << i)) cnt++;
if (cnt >= K)
{
for (int t = ; t < sz ; t++)
ret = (ret + dp[cur][t][j]) % MOD;
}
}
return ret;
}
}src;
int main()
{
//freopen("sample.txt","r",stdin);
while (scanf("%d%d%d",&N,&M,&K) != EOF)
{
if (N == && M == && K == ) break;
src.init();
for (int i = ; i < M; i++)
{
char tmp[];
scanf("%s",tmp);
src.insert(tmp, << i);
}
src.get_fail();
printf("%d\n",src.calcu(N, << M,K));
}
return ;
}

HDU 2296 Ring

题目:给出m个模式串,每个串有一定的分值,构造一个长度不超过n的串,使得分值最大,输出长度最小,字典序最小的串

#include <map>
#include <set>
#include <list>
#include <cmath>
#include <ctime>
#include <deque>
#include <stack>
#include <queue>
#include <cctype>
#include <cstdio>
#include <string>
#include <vector>
#include <climits>
#include <cstdlib>
#include <cstring>
#include <iostream>
#include <algorithm>
#define LL long long
#define PI 3.1415926535897932626
using namespace std;
int gcd(int a, int b) {return a % b == ? b : gcd(b, a % b);}
const int MAXNNODE = ;
const int SIGMA_SIZE = ;
const int INF = 0x3f3f3f3f;
int N,M;
int h[MAXNNODE];
char res[][MAXNNODE][]; bool cmp(char * s,char * t)
{
int len1 = strlen(s);
int len2 = strlen(t);
if (len1 != len2) return len1 < len2;
return strcmp(s,t) < ;
} struct Ac_Automation
{
int ch[MAXNNODE][SIGMA_SIZE];
int val[MAXNNODE];
int fail[MAXNNODE],last[MAXNNODE];
int sz;
LL dp[][MAXNNODE];
Ac_Automation() {sz = ;memset(ch[],,sizeof(ch[]));}
int idx(char c) {return c - 'a';} void insert(char * s,int v)
{
int u = ,n = strlen(s);
for (int i = ; i < n ; i++)
{
int c = idx(s[i]);
if (!ch[u][c])
{
memset(ch[sz],,sizeof(ch[sz]));
val[sz] = ;
ch[u][c] = sz++;
}
u = ch[u][c];
}
val[u] = v;//最后的叶子节点给与信息v
// printf("%d %d\n",u,v);
} //建立字典树 void get_fail()
{
queue<int>q;
fail[] = ;
for (int c = ; c < SIGMA_SIZE ; c++)
{
int u = ch[][c];
if (u)
{
fail[u] = ;
q.push(u);
last[u] = ;
}
}
while (!q.empty())
{
int r = q.front();q.pop();
for (int c = ; c < SIGMA_SIZE ; c++)
{
int u = ch[r][c];
if (u == )
{
ch[r][c] = ch[fail[r]][c];
continue;
}
q.push(u);
int v = fail[r];
while (v && !ch[v][c]) v = fail[v];
fail[u] = ch[v][c];
last[u] = val[fail[u]] ? fail[u] : last[fail[u]];
}
}
} void print(int j)
{
if (j)
{
// printf("%d\n",val[j]);
// cnt[val[j]]++;
print(last[j]);
}
} void Find(char * T)
{
int n = strlen(T);
int j = ;
for (int i = ; i < n ; i++)
{
int c = idx(T[i]);
// while(j && !ch[j][c]) j = f[j];
j = ch[j][c];
if (val[j]) print(j);
else if (last[j]) print(last[j]);//print是功能函数
}
} void init()
{
sz = ;
memset(ch[],,sizeof(ch[]));
} void calcu()
{
for (int i = ; i <= N ; i++)
for (int j = ; j < sz ; j++) dp[i][j] = -INF;
dp[][] = ;
strcpy(res[][],"");
char ret[];
strcpy(ret,"");
int MAX = ;
char tmp[];
for (int i = ; i < N ; i++)
{
for (int j = ; j < sz ; j++)
{
if (dp[i][j] < ) continue;
strcpy(tmp,res[i][j]);
int len = strlen(tmp);
for (int k = ; k < SIGMA_SIZE ; k++)
{
int nxt = ch[j][k];
tmp[len] = k + 'a';
tmp[len + ] = '\0';
//len++;
int value = dp[i][j];
if (val[nxt]) value += h[val[nxt]];
// if (value != 0) printf("%s %d\n",tmp);
if (dp[i + ][nxt] < value || (dp[i + ][nxt] == value && cmp(tmp,res[i + ][nxt])))
{
dp[i + ][nxt] = value;
strcpy(res[i + ][nxt],tmp);
if (value > MAX || (value == MAX && cmp(tmp,ret)))
{
MAX = value;
strcpy(ret,tmp);
}
}
}
}
}
// printf("%d\n",MAX);
printf("%s\n",ret);
}
}src; int main()
{
int T;
char buf[];
scanf("%d",&T);
while (T--)
{
scanf("%d%d",&N,&M);
src.init();
for (int i = ; i < M ; i++)
{
scanf("%s",buf);
src.insert(buf,i + );
}
for (int i = ; i <= M ; i++) scanf("%d",&h[i]);
src.get_fail();
src.calcu();
}
return ;
}

HDU 2457 DNA repair

题目:给出一些不合法的模式DNA串,给出一个原串,问最少需要修改多少个字符,使得原串中不包含非法串

#include <map>
#include <set>
#include <list>
#include <cmath>
#include <ctime>
#include <deque>
#include <stack>
#include <queue>
#include <cctype>
#include <cstdio>
#include <string>
#include <vector>
#include <climits>
#include <cstdlib>
#include <cstring>
#include <iostream>
#include <algorithm>
#define LL long long
#define PI 3.1415926535897932626
using namespace std;
int gcd(int a, int b) {return a % b == ? b : gcd(b, a % b);}
const int MAXNNODE = ;
const int SIGMA_SIZE = ;
struct Ac_Automation
{
int ch[MAXNNODE][SIGMA_SIZE];
int val[MAXNNODE];
int fail[MAXNNODE],last[MAXNNODE];
int sz;
Ac_Automation() {sz = ;memset(ch[],,sizeof(ch[]));}
int idx(char c)
{
if (c == 'A') return ;
if (c == 'G') return ;
if (c == 'C') return ;
if (c == 'T') return ;
} void insert(char * s,int v)
{
int u = ,n = strlen(s);
for (int i = ; i < n ; i++)
{
int c = idx(s[i]);
if (!ch[u][c])
{
memset(ch[sz],,sizeof(ch[sz]));
val[sz] = ;
ch[u][c] = sz++;
}
u = ch[u][c];
}
val[u] = v;//最后的叶子节点给与信息v
} //建立字典树 void get_fail()
{
queue<int>q;
for (int c = ; c < SIGMA_SIZE ; c++)
{
int u = ch[][c];
if (u)
{
fail[u] = ;
q.push(u);
last[u] = ;
}
}
while (!q.empty())
{
int r = q.front();q.pop();
if (val[fail[r]])
val[r] = true;
for (int c = ; c < SIGMA_SIZE ; c++)
{
int u = ch[r][c];
if (u == )
{
ch[r][c] = ch[fail[r]][c];
continue;
}
q.push(u);
int v = fail[r];
while (v && !ch[v][c]) v = fail[v];
fail[u] = ch[v][c];
last[u] = val[fail[u]] ? fail[u] : last[fail[u]];
}
}
} void print(int j)
{
if (j)
{
// printf("%d\n",val[j]);
//cnt[val[j]]++;
print(last[j]);
}
} void Find(char * T)
{
int n = strlen(T);
int j = ;
for (int i = ; i < n ; i++)
{
int c = idx(T[i]);
// while(j && !ch[j][c]) j = f[j];
j = ch[j][c];
if (val[j]) print(j);
else if (last[j]) print(last[j]);//print是功能函数
}
} void init()
{
sz = ;
memset(ch[],,sizeof(ch[]));
}
}src;
int dp[][];
int N;
char str[];
int main()
{
// freopen("sample.txt","r",stdin);
int kase = ;
while (scanf("%d",&N) != EOF)
{
if (N == ) break;
src.init();
memset(dp,-,sizeof(dp));
for (int i = ; i < N; i++)
{
scanf("%s",str);
src.insert(str,);
}
src.get_fail();
scanf("%s",str + );
int len = strlen(str + );
dp[][] = ;
for (int i = ; i < len ; i++)
{
for (int j = ; j < src.sz ; j++)
{
if (dp[i][j] == -) continue;
int idx = src.idx(str[i + ]);
for (int k = ; k < ; k++)
{
int add = ;
if (k != idx) add = ;
if (src.val[src.ch[j][k]]) continue;
if (dp[i + ][src.ch[j][k]] == -) dp[i + ][src.ch[j][k]] = dp[i][j] + add;
else dp[i + ][src.ch[j][k]] = min(dp[i + ][src.ch[j][k]],dp[i][j] + add);
}
}
}
int ret = INT_MAX;
for (int i = ; i < src.sz ; i++)
{
if (dp[len][i] == -) continue;
ret = min(ret,dp[len][i]);
}
printf("Case %d: %d\n",kase++,ret == INT_MAX ? - : ret);
}
return ;
}

ZOJ 3228 Searching the String

计算可重叠不可重叠字串出现在主串的次数

可重叠就是裸地AC自动机。

不可重叠,记录字典树上每个点的深度,没匹配到一个模式串,记录一下位置,

#include <map>
#include <set>
#include <list>
#include <cmath>
#include <ctime>
#include <deque>
#include <stack>
#include <queue>
#include <cctype>
#include <cstdio>
#include <string>
#include <vector>
#include <climits>
#include <cstdlib>
#include <cstring>
#include <iostream>
#include <algorithm>
#define LL long long
#define PI 3.1415926535897932626
using namespace std;
int gcd(int a, int b) {return a % b == ? b : gcd(b, a % b);}
const int MAXNNODE = ;
const int SIGMA_SIZE = ;
const int INF = 0x3f3f3f3f;
int pos[MAXNNODE / ],N;
char str[MAXNNODE / ]; struct Ac_Automation
{
int ch[MAXNNODE][SIGMA_SIZE];
int val[MAXNNODE];
int fail[MAXNNODE],last[MAXNNODE];
int depth[MAXNNODE],pre[MAXNNODE];
int cnt[MAXNNODE][];
int sz;
Ac_Automation() {sz = ;memset(ch[],,sizeof(ch[]));}
int idx(char c) {return c - 'a';} int insert(char * s,int v)
{
int u = ,n = strlen(s);
for (int i = ; i < n ; i++)
{
int c = idx(s[i]);
if (!ch[u][c])
{
memset(ch[sz],,sizeof(ch[sz]));
val[sz] = ;
depth[sz] = i + ;
ch[u][c] = sz++;
}
u = ch[u][c];
}
val[u] += v;//最后的叶子节点给与信息v
return u;
} //建立字典树 void get_fail()
{
queue<int>q;
fail[] = ;
for (int c = ; c < SIGMA_SIZE ; c++)
{
int u = ch[][c];
if (u)
{
fail[u] = ;
q.push(u);
last[u] = ;
}
}
while (!q.empty())
{
int r = q.front();q.pop();
for (int c = ; c < SIGMA_SIZE ; c++)
{
int u = ch[r][c];
if (u == )
{
ch[r][c] = ch[fail[r]][c];
continue;
}
q.push(u);
int v = fail[r];
while (v && !ch[v][c]) v = fail[v];
fail[u] = ch[v][c];
last[u] = val[fail[u]] ? fail[u] : last[fail[u]];
}
}
} void print(int i,int j)
{
if (j)
{
// printf("%d\n",val[j]);
cnt[j][]++;
if (i - pre[j] >= depth[j])
{
cnt[j][]++;
pre[j] = i;
}
print(i,last[j]);
}
} void Find(char * T)
{
int n = strlen(T);
int j = ;
for (int i = ; i < n ; i++)
{
int c = idx(T[i]);
// while(j && !ch[j][c]) j = f[j];
j = ch[j][c];
if (val[j]) print(i,j);
else if (last[j]) print(i,last[j]);//print是功能函数
}
} void init()
{
sz = ;
memset(ch[],,sizeof(ch[]));
memset(pre,-,sizeof(pre));
memset(cnt,,sizeof(cnt));
memset(val,,sizeof(val));
}
}src; int flag[MAXNNODE / ];
int main()
{
int kase = ;
while (scanf("%s",str) != EOF)
{
scanf("%d",&N);
src.init();
for (int i = ; i < N ; i++)
{
char tmp[];
scanf("%d%s",&flag[i],tmp);
pos[i] = src.insert(tmp,);
}
src.get_fail();
src.Find(str);
printf("Case %d\n",kase++);
for (int i = ; i < N ; i++)
printf("%d\n",src.cnt[pos[i]][flag[i]]);
puts("");
}
return ;
}

HDU 3247  Resource Archiver

题目:给出n个资源,m个病毒,将资源串拼接成一个串,必须包含所有的资源串,可以重叠,但是不能包含病毒

问最小的长度为多少

所有的资源串和病毒串都放在Trie树里建立起来,当然作上相应的标记。然后建立fail指针之后

从资源串的结尾出发,BFS,记录能到达其它资源串结尾的步数。得到所有资源串结尾状态的距离邻接阵。

之后是状态压缩DP

#include <map>
#include <set>
#include <list>
#include <cmath>
#include <ctime>
#include <deque>
#include <stack>
#include <queue>
#include <cctype>
#include <cstdio>
#include <string>
#include <vector>
#include <climits>
#include <cstdlib>
#include <cstring>
#include <iostream>
#include <algorithm>
#define LL long long
#define PI 3.1415926535897932626
using namespace std;
int gcd(int a, int b) {return a % b == ? b : gcd(b, a % b);}
const int MAXNNODE = ;
const int SIGMA_SIZE = ;
const int INF = 0x3f3f3f3f;
int pos[];
struct Ac_Automation
{
int ch[MAXNNODE][SIGMA_SIZE];
int val[MAXNNODE];
int state[MAXNNODE];
int fail[MAXNNODE],last[MAXNNODE];
int sz;
Ac_Automation() {sz = ;memset(ch[],,sizeof(ch[]));}
int idx(char c) {if (c == '') return ; return ;} void insert(char * s,bool v,int id = -)
{
int u = ,n = strlen(s);
for (int i = ; i < n ; i++)
{
int c = idx(s[i]);
if (!ch[u][c])
{
memset(ch[sz],,sizeof(ch[sz]));
val[sz] = ;
state[sz] = ;
ch[u][c] = sz++;
}
u = ch[u][c];
}
if (!v)
{
pos[id] = u;
state[u] |= ( << id);
//printf("%d %d\n",u,state[u]);
}
val[u] = val[u] || v;//最后的叶子节点给与信息v
} //建立字典树 void get_fail()
{
queue<int>q;
fail[] = ;
for (int c = ; c < SIGMA_SIZE ; c++)
{
int u = ch[][c];
if (u)
{
fail[u] = ;
q.push(u);
last[u] = ;
}
}
while (!q.empty())
{
int r = q.front();q.pop();
val[r] |= val[fail[r]]; //use in dp problem
state[r] |= state[fail[r]];
for (int c = ; c < SIGMA_SIZE ; c++)
{
int u = ch[r][c];
if (u == )
{
ch[r][c] = ch[fail[r]][c];
continue;
}
q.push(u);
int v = fail[r];
while (v && !ch[v][c]) v = fail[v];
fail[u] = ch[v][c];
last[u] = val[fail[u]] ? fail[u] : last[fail[u]];
}
}
} void print(int j)
{
if (j)
{
// printf("%d\n",val[j]);
//cnt[val[j]]++;
print(last[j]);
}
} void Find(char * T)
{
int n = strlen(T);
int j = ;
for (int i = ; i < n ; i++)
{
int c = idx(T[i]);
// while(j && !ch[j][c]) j = f[j];
j = ch[j][c];
if (val[j]) print(j);
else if (last[j]) print(last[j]);//print是功能函数
}
} void init()
{
sz = ;
memset(ch[],,sizeof(ch[]));
memset(val,,sizeof(val));
memset(state,,sizeof(state));
}
}src; int dist[][MAXNNODE];
char str[];
int length[];
int dp[][]; void bfs(int id,int st)
{
//printf("%d %d\n",id,st);
for (int i = ; i < src.sz ; i++) dist[id][i] = INF;
dist[id][st] = ;
queue<int>q;
q.push(st);
while (!q.empty())
{
int u = q.front();
q.pop();
int v = src.ch[u][];
if (!src.val[v] && dist[id][v] == INF)
{
dist[id][v] = dist[id][u] + ;;
q.push(v);
}
v = src.ch[u][];
if (!src.val[v] && dist[id][v] == INF)
{
dist[id][v] = dist[id][u] + ;
q.push(v);
}
}
} void calcu(int n)
{
int limit = ( << n);
for (int i = ; i <= n ; i++)
for (int j = ; j < limit ; j++) dp[i][j] = INF;
for (int i = ; i < n ; i++)
dp[i][ << i] = length[i];
for (int i = ; i < limit ; i++)
{
for (int j = ; j < n ; j++)
{
if ((i & ( << j)) && dp[j][i] != INF)
{
for (int k = ; k < n ; k++)
{
int nxt = i | src.state[pos[k]];
dp[k][nxt] = min(dp[k][nxt],dp[j][i] + dist[j][pos[k]]);
}
}
}
}
int ret = INF;
for (int i = ; i < n ; i++)
ret = min(ret,dp[i][limit - ]);
printf("%d\n",ret);
} int main()
{
int N,M;
while (scanf("%d%d",&N,&M) != EOF)
{
if (N == && M == ) break;
src.init();
memset(length,,sizeof(length));
for (int i = ; i < N ; i++)
{
scanf("%s",str);
length[i] = strlen(str);
src.insert(str,false,i);
}
for (int i = ; i < M ; i++)
{
scanf("%s",str);
src.insert(str,true);
}
src.get_fail();
// printf("%d\n",src.sz);
// for (int i = 0 ; i < 9 ; i++)printf("%d %d\n",i,src.val[i]);
for (int i = ; i < N ; i++) bfs(i,pos[i]);
calcu(N);
}
return ;
}

ZOJ 3494 BCD CODE

题目:给出一些模式串,给出一个范围[A,B],求出区间内有多少个数,写成BCD之后,不包含模式串

使用AC自动机,得到bcd[i][j]表示状态i,加了数字j以后到达的状态,为-1表示不能转移

然后就是数位DP了

#include <map>
#include <set>
#include <list>
#include <cmath>
#include <ctime>
#include <deque>
#include <stack>
#include <queue>
#include <cctype>
#include <cstdio>
#include <string>
#include <vector>
#include <climits>
#include <cstdlib>
#include <cstring>
#include <iostream>
#include <algorithm>
#define LL long long
#define PI 3.1415926535897932626
using namespace std;
int gcd(int a, int b) {return a % b == ? b : gcd(b, a % b);}
const int MAXNNODE = ;
const int SIGMA_SIZE = ;
struct Ac_Automation
{
int ch[MAXNNODE][SIGMA_SIZE];
int val[MAXNNODE];
int fail[MAXNNODE],last[MAXNNODE];
int sz;
Ac_Automation() {sz = ;memset(ch[],,sizeof(ch[]));}
int idx(char c) {return c - '';} void insert(char * s,int v)
{
int u = ,n = strlen(s);
for (int i = ; i < n ; i++)
{
int c = idx(s[i]);
if (!ch[u][c])
{
memset(ch[sz],,sizeof(ch[sz]));
val[sz] = ;
ch[u][c] = sz++;
}
u = ch[u][c];
}
val[u] = v;//最后的叶子节点给与信息v
} //建立字典树 void get_fail()
{
queue<int>q;
fail[] = ;
for (int c = ; c < SIGMA_SIZE ; c++)
{
int u = ch[][c];
if (u)
{
fail[u] = ;
q.push(u);
last[u] = ;
}
}
while (!q.empty())
{
int r = q.front();q.pop();
if (val[fail[r]]) val[r] = ;
//val[r] += val[fail[r]]; use in dp problem
for (int c = ; c < SIGMA_SIZE ; c++)
{
int u = ch[r][c];
if (u == )
{
ch[r][c] = ch[fail[r]][c];
continue;
}
q.push(u);
int v = fail[r];
while (v && !ch[v][c]) v = fail[v];
fail[u] = ch[v][c];
last[u] = val[fail[u]] ? fail[u] : last[fail[u]];
}
}
} void print(int j)
{
if (j)
{
// printf("%d\n",val[j]);
// cnt[val[j]]++;
print(last[j]);
}
} void Find(char * T)
{
int n = strlen(T);
int j = ;
for (int i = ; i < n ; i++)
{
int c = idx(T[i]);
// while(j && !ch[j][c]) j = f[j];
j = ch[j][c];
if (val[j]) print(j);
else if (last[j]) print(last[j]);//print是功能函数
}
} void init()
{
sz = ;
memset(ch[],,sizeof(ch[]));
memset(val,,sizeof(val));
}
}src; int bcd[MAXNNODE][];
int trans(int pre,int num)
{
if (src.val[pre]) return -;
int cur = pre;
for (int i = ; i >= ; i--)
{
if (src.val[src.ch[cur][(num >> i) & ]]) return -;
cur = src.ch[cur][(num >> i) & ];
}
return cur;
} void init()
{
for (int i = ; i < src.sz ; i++)
for (int j = ; j < ; j++)
bcd[i][j] = trans(i,j);
} const int MOD = ;
LL dp[][MAXNNODE];
int digit[]; LL dfs(int length,int s,bool ismax,bool zero)
{
if (length == ) return ;
if (!ismax && dp[length][s] >= ) return dp[length][s];
LL ans = ;
if (length > && zero)
{
ans += dfs(length - ,s,ismax && digit[length] == ,true);
ans %= MOD;
}
else
{
if (bcd[s][] != -)
{
ans += dfs(length - ,bcd[s][],ismax && digit[length] == ,false);
ans %= MOD;
}
}
int limit = ismax ? digit[length] : ;
for (int i = ; i <= limit ; i++)
{
if (bcd[s][i] != -)
{
ans += dfs(length - ,bcd[s][i],ismax && i == limit ,false);
ans %= MOD;
}
}
if (!ismax && !zero) dp[length][s] = ans;
return ans;
} LL calcu(char * s)
{
int len = strlen(s + );
for (int i = ,j = len ; i <= len ; i++,j--)
digit[j] = s[i] - '';
// for (int j = 1 ; j <= len ; j++) printf("%d ",digit[j]); puts("");
return dfs(len,,true,true);
} char str[];
int main()
{
int T;
scanf("%d",&T);
while (T--)
{
int n;
src.init();
scanf("%d",&n);
for (int i = ; i < n ; i++)
{
scanf("%s",str);
src.insert(str,);
}
src.get_fail();
init();
memset(dp,-,sizeof(dp));
LL ans = ;
scanf("%s",str + );
int len = strlen(str + );
for (int i = len ; i >= ; i--)
{
if (str[i] > '')
{
str[i]--;
break;
}
else str[i] = '';
}
ans -= calcu(str);
ans %= MOD;
//cout << calcu(str) << endl;
scanf("%s",str + );
// cout << calcu(str) << endl;
ans += calcu(str);
ans %= MOD;
if (ans < ) ans += MOD;
printf("%lld\n",ans);
}
return ;
}

HDU 4758 Walk Through Squares

题意:给n*m的地图,在地图的点上走,(n+1)*(m+1)个点,两种操作:往下走D和往右走R。现在要从左上角走到右下角,给定两个操作串,问包含这两个串的走法总共有多少种。

#include <map>
#include <set>
#include <list>
#include <cmath>
#include <ctime>
#include <deque>
#include <stack>
#include <queue>
#include <cctype>
#include <cstdio>
#include <string>
#include <vector>
#include <climits>
#include <cstdlib>
#include <cstring>
#include <iostream>
#include <algorithm>
#define LL long long
#define PI 3.1415926535897932626
using namespace std;
int gcd(int a, int b) {return a % b == ? b : gcd(b, a % b);}
const int MOD = 1e9 + ;
const int MAXNNODE = ;
const int SIGMA_SIZE = ;
int dp[][][][];
int M,N;
struct Ac_Automation
{
int ch[MAXNNODE][SIGMA_SIZE];
int val[MAXNNODE];
int fail[MAXNNODE],last[MAXNNODE];
int sz;
Ac_Automation() {sz = ;memset(ch[],,sizeof(ch[]));}
int idx(char c)
{
if (c == 'R') return ;
else return ;
} void insert(char * s,int v)
{
int u = ,n = strlen(s);
for (int i = ; i < n ; i++)
{
int c = idx(s[i]);
if (ch[u][c] == )
{
memset(ch[sz],,sizeof(ch[sz]));
val[sz] = ;
ch[u][c] = sz++;
}
u = ch[u][c];
}
val[u] = v;//最后的叶子节点给与信息v
} //建立字典树 void get_fail()
{
queue<int>q;
// fail[0] = 0;
for (int c = ; c < SIGMA_SIZE ; c++)
{
int u = ch[][c];
if (u != )
{
fail[u] = ;
q.push(u);
last[u] = ;
}
//else ch[0][c] = 0;
}
while (!q.empty())
{
int r = q.front();q.pop();
if(val[fail[r]]) val[r] |= val[fail[r]];
for (int c = ; c < SIGMA_SIZE ; c++)
{
int u = ch[r][c];
if (u == )
{
ch[r][c] = ch[fail[r]][c];
continue;
}
q.push(u);
int v = fail[r];
while (v && !ch[v][c]) v = fail[v];
fail[u] = ch[v][c];
last[u] = val[fail[u]] ? fail[u] : last[fail[u]];
val[u] |= val[fail[u]];
}
}
} void print(int j)
{
if (j)
{
// printf("%d\n",val[j]);
//cnt[val[j]]++;
print(last[j]);
}
} void Find(char * T)
{
int n = strlen(T);
int j = ;
for (int i = ; i < n ; i++)
{
int c = idx(T[i]);
// while(j && !ch[j][c]) j = f[j];
j = ch[j][c];
if (val[j]) print(j);
else if (last[j]) print(last[j]);//print是功能函数
}
} void init()
{
sz = ;
memset(ch[],,sizeof(ch[]));
memset(val,,sizeof());
val[] = ;
} void slove()
{
memset(dp,,sizeof(dp));
dp[][][][] = ;
for (int i = ; i <= M ; i++)
for (int j = ; j <= N; j++)
for (int s = ; s < sz ; s++)
for (int k = ; k < ; k++)
{
if (dp[i][j][s][k] == ) continue;
int nxt = ch[s][];
if (i < M)
dp[i + ][j][nxt][k | val[nxt]] = (dp[i + ][j][nxt][k | val[nxt]]
+ dp[i][j][s][k]) % MOD;
nxt = ch[s][];
if (j < N)
dp[i][j + ][nxt][k | val[nxt]] = (dp[i][j + ][nxt][k | val[nxt]]
+ dp[i][j][s][k]) % MOD;
}
int ret = ;
for (int i = ; i < sz ; i++)
ret = (ret + dp[M][N][i][]) % MOD;
printf("%d\n",ret);
}
}src; int main()
{
//freopen("sample.txt","r",stdin);
int T;
scanf("%d",&T);
while (T--)
{
scanf("%d%d",&M,&N);
src.init();
for (int i = ; i < ; i++)
{
char str[];
scanf("%s",str);
src.insert(str, << i);
}
src.get_fail();
src.slove();
// for (int i = 0 ; i < src.sz ; i++)
// printf("%d %d\n",src.ch[i][0],src.ch[i][1]);
}
return ;
}

HDU 4511 小明系列故事――女友的考验

#include <map>
#include <set>
#include <list>
#include <cmath>
#include <ctime>
#include <deque>
#include <stack>
#include <queue>
#include <cctype>
#include <cstdio>
#include <string>
#include <vector>
#include <climits>
#include <cstdlib>
#include <cstring>
#include <iostream>
#include <algorithm>
#define LL long long
#define PI 3.1415926535897932626
using namespace std;
int gcd(int a, int b) {return a % b == ? b : gcd(b, a % b);}
const double INF = 1e20;
const int MAXNNODE = ;
const int SIGMA_SIZE = ;
double dp[][MAXNNODE];
int N,M;
struct node
{
double x,y;
}input[];
double dist(int i ,int j)
{
return sqrt((input[i].x - input[j].x) * (input[i].x - input[j].x) +
(input[i].y - input[j].y) * (input[i].y - input[j].y));
}
struct Ac_Automation
{
int ch[MAXNNODE][SIGMA_SIZE];
int val[MAXNNODE];
int fail[MAXNNODE],last[MAXNNODE];
int sz;
Ac_Automation() {sz = ;memset(ch[],,sizeof(ch[]));}
int idx(int c) {return c;} void insert(int * s,int v,int n)
{
int u = ;
for (int i = ; i < n ; i++)
{
int c = idx(s[i]);
if (!ch[u][c])
{
memset(ch[sz],,sizeof(ch[sz]));
val[sz] = ;
ch[u][c] = sz++;
}
u = ch[u][c];
}
val[u] = v;//最后的叶子节点给与信息v
} //建立字典树 void get_fail()
{
queue<int>q;
fail[] = ;
for (int c = ; c < SIGMA_SIZE ; c++)
{
int u = ch[][c];
if (u)
{
fail[u] = ;
q.push(u);
last[u] = ;
}
}
while (!q.empty())
{
int r = q.front();q.pop();
val[r] |= val[fail[r]];
for (int c = ; c < SIGMA_SIZE ; c++)
{
int u = ch[r][c];
if (u == )
{
ch[r][c] = ch[fail[r]][c];
continue;
}
q.push(u);
int v = fail[r];
while (v && !ch[v][c]) v = fail[v];
fail[u] = ch[v][c];
last[u] = val[fail[u]] ? fail[u] : last[fail[u]];
}
}
} void print(int j)
{
if (j)
{
// printf("%d\n",val[j]);
//cnt[val[j]]++;
print(last[j]);
}
} void Find(char * T)
{
int n = strlen(T);
int j = ;
for (int i = ; i < n ; i++)
{
int c = idx(T[i]);
// while(j && !ch[j][c]) j = f[j];
j = ch[j][c];
if (val[j]) print(j);
else if (last[j]) print(last[j]);//print是功能函数
}
} void init()
{
sz = ;
memset(ch[],,sizeof(ch[]));
} double slove()
{
for (int i = ; i < MAXNNODE ; i++)
for (int j = ; j < ; j++) dp[j][i] = INF;
dp[][ch[][]] = 0.0;
for (int i = ; i <= N; i++)
for (int j = ; j < sz ; j++)
{
if (dp[i][j] == INF) continue;
for (int k = i + ; k <= N; k++)
{
int nxt = ch[j][k];
if (val[nxt]) continue;
dp[k][nxt] = min(dp[k][nxt],dp[i][j] + dist(i,k));
}
}
double ret = INF;
for (int i = ; i < sz ; i++)
ret = min(ret,dp[N][i]);
return ret;
}
}src;
int main()
{
// freopen("sample.txt","r",stdin);
while (scanf("%d%d",&N,&M) != EOF)
{
if (N == && M == ) break;
src.init();
for (int i = ; i <= N; i++) scanf("%lf%lf",&input[i].x,&input[i].y);
for (int i = ; i < M; i++)
{
int k;
scanf("%d",&k);
int tmp[];
for (int i = ; i < k ; i++) scanf("%d",&tmp[i]);
src.insert(tmp,,k);
}
src.get_fail();
double ret = src.slove();
if (ret == INF) puts("Can not be reached!");
else printf("%.2lf\n",ret);
}
return ;
}

Kuangbin带你飞 AC自动机的更多相关文章

  1. 「kuangbin带你飞」专题十七 AC自动机

    layout: post title: 「kuangbin带你飞」专题十七 AC自动机 author: "luowentaoaa" catalog: true tags: - ku ...

  2. KUANGBIN带你飞

    KUANGBIN带你飞 全专题整理 https://www.cnblogs.com/slzk/articles/7402292.html 专题一 简单搜索 POJ 1321 棋盘问题    //201 ...

  3. [kuangbin带你飞]专题1-23题目清单总结

    [kuangbin带你飞]专题1-23 专题一 简单搜索 POJ 1321 棋盘问题POJ 2251 Dungeon MasterPOJ 3278 Catch That CowPOJ 3279 Fli ...

  4. 「kuangbin带你飞」专题十四 数论基础

    layout: post title: 「kuangbin带你飞」专题十四 数论基础 author: "luowentaoaa" catalog: true tags: mathj ...

  5. 「kuangbin带你飞」专题十二 基础DP

    layout: post title: 「kuangbin带你飞」专题十二 基础DP author: "luowentaoaa" catalog: true tags: mathj ...

  6. 【算法系列学习三】[kuangbin带你飞]专题二 搜索进阶 之 A-Eight 反向bfs打表和康拓展开

    [kuangbin带你飞]专题二 搜索进阶 之 A-Eight 这是一道经典的八数码问题.首先,简单介绍一下八数码问题: 八数码问题也称为九宫问题.在3×3的棋盘,摆有八个棋子,每个棋子上标有1至8的 ...

  7. Tarjan 联通图 Kuangbin 带你飞 联通图题目及部分联通图题目

    Tarjan算法就不说了 想学看这 https://www.byvoid.com/blog/scc-tarjan/ https://www.byvoid.com/blog/biconnect/ 下面是 ...

  8. 「kuangbin带你飞」专题二十 斜率DP

    layout: post title: 「kuangbin带你飞」专题二十 斜率DP author: "luowentaoaa" catalog: true tags: mathj ...

  9. 「kuangbin带你飞」专题二十二 区间DP

    layout: post title: 「kuangbin带你飞」专题二十二 区间DP author: "luowentaoaa" catalog: true tags: - ku ...

随机推荐

  1. 把python脚本打包成win可执行文件

    前几天有个朋友找我写一点小东西,写好后把代码发他帮他搞了半天,结果愣是没听懂,就找到了这个办法. 1.导入pyinstaller包, pip install pyinstaller 2.进入到你需要打 ...

  2. tp5 项目实战 初级 文字步骤

    项目实战 环境搭建 新建模块  admin 新建文件夹 controller   model  view View   中新建 user  index 相关样式  js   图片     放入publ ...

  3. python终极篇 --- django 初识

    1. 下载: 命令行: pip install django==1.11.15 pip install -i 源 django==1.11.15 pycharm settings 解释器 点+号 输入 ...

  4. String 将GBK转UTF-8

    public void transfer(String xml) throws Exception { return new String(xml.getBytes("gbk"), ...

  5. C++ STL容器——stack用法介绍

    stack是一种容器适配器,专门设计用于在LIFO上下文中操作(后进先出),其中元素仅从容器的一端插入和删除. 容器适配器,而不是一种容器. 它是容器适配器是指,只要支持一系列方法的容器(empty, ...

  6. Ubuntu 进阶命令——长期不定时更新

    有时候远程连接服务器忽然中断或者不小心关掉了终端界面,正在运行的命令或者程序就会被强制停止.这时候,我们可以借助一些命令来避免这种情况的发生. nohup 不挂断地运行命令 & 在后台运行命令 ...

  7. php处理三级分类数据

    <?php // 链接数据库 $link = mysqli_connect('localhost','root','root'); if($link == null){ exit; } mysq ...

  8. shell功能

    日志切割: function rotate() { logs_path=$ echo Rotating Log: $ cp ${logs_path} ${logs_path}.$(date -d &q ...

  9. Python参考

    python中os模块用法 自动化运维Python系列(五)之常用模块 最常用的Notepad++的快捷键 pycharm快捷键 最全Pycharm教程(1)——定制外观 pycharm教程大全 py ...

  10. OpenCV尺寸调整

    #include<cv.h> #include<highgui.h> int main(int argc, char** argv) { IplImage* img = cvL ...