文章目录

  • 后缀自动机
  • 算法实现过程
  • 模板
  • 习题
    • 洛谷后缀自动机模板题
    • 品酒大会
    • [HEOI2015]最短不公共子串
    • 字符串

蒟蒻写这篇blogblogblog主要是存一下,后缀自动机的详细搭建过程,方便以后复习
具体的某些证明,为什么这么做,正确性劈里啪啦一大堆就不赘述了讲解指路☞

后缀自动机

后缀自动机上每一条到iii的路径对应一个子串,整个自动机包含了字符串的所有子串

很多时候可以和后缀数组等价使用


endposendposendpos:一个子串iii在整个字符串中出现的位置 最后一个字符的下标 构成的集合
举个栗子 abcbcdeabcabcbcdeabcabcbcdeabc,(从000开始标号)
子串abcabcabc对应的endposendposendpos为{2,9}\{2,9\}{2,9},子串bcbcbc的endposendposendpos为{2,4,9}\{2,4,9\}{2,4,9}

后缀自动机的编号对应的就是endposendposendpos完全相同的所有子串
依旧是上面的粒子abcbcdeabcabcbcdeabcabcbcdeabc
子串bcbcbc的endposendposendpos为{2,4,9}\{2,4,9\}{2,4,9},子串ccc的endposendposendpos也为{2,4,9}\{2,4,9\}{2,4,9}
那么后缀自动机上对应的ididid编号既表示bcbcbc子串,也表示ccc子串

算法实现过程


  • e.g.1e.g.1e.g.1,构建abcdabcdabcd的后缀自动机
    Ⅰ最初始状态,仅有一个空根,last=1last=1last=1,lastlastlast表示后缀自动机的最后一个节点

    Ⅱ 将′a′'a'′a′扔进去,新建一个节点cnt=2cnt=2cnt=2,len=len[last]+1=1len=len[last]+1=1len=len[last]+1=1
    从lastlastlast开始跳,发现111没有′a′'a'′a′边
    则建立一条′a′'a'′a′边,并指向新点222
    此时跳到了初始源点,222的后缀链接只能指向111,lastlastlast变为222

    Ⅲ 将′b′'b'′b′扔进去,新建一个节点cnt=3,len=len[last]+1=2cnt=3,len=len[last]+1=2cnt=3,len=len[last]+1=2
    从lastlastlast开始跳后缀链接
    222没有′b′'b'′b′边,新建一条并指向333,跳后缀链接到111
    111没有′b′'b'′b′边,新建一条并指向333
    此时已经到了根节点,333的后缀链接只能指向111,last=3last=3last=3

    Ⅳ 将′c′'c'′c′扔进去,新建一个节点cnt=4,len=3cnt=4,len=3cnt=4,len=3
    从lastlastlast开始跳后缀链接
    333没有′c′'c'′c′边,新建一条并指向444,跳后缀链接到111
    111没有′c′'c'′c′边,新建一条并指向444
    此时已经到了根节点,444的后缀链接只能指向111,last=4last=4last=4
    Ⅴ 将′d′'d'′d′扔进去,新建一个节点cnt=5,len=4cnt=5,len=4cnt=5,len=4
    从lastlastlast开始跳后缀链接
    444没有′c′'c'′c′边,新建一条并指向555,跳后缀链接到111
    111没有′c′'c'′c′边,新建一条并指向555
    此时已经到了根节点,555的后缀链接只能指向111,last=5last=5last=5

    最简单的一种后缀自动机就完成了
    接下来就尝试一下进阶版

  • e.g.2e.g.2e.g.2,构建ababeababeababe的后缀自动机
    Ⅰ先搭建空源点,last=1last=1last=1

    Ⅱ 加入′a′'a'′a′,新建一个节点cnt=2,len[2]=len[last]+1=1cnt=2,len[2]=len[last]+1=1cnt=2,len[2]=len[last]+1=1
    111没有′c′'c'′c′边,新建一条并指向222,
    此时已经到了根节点,222的后缀链接只能指向111,last=2last=2last=2

    Ⅲ 加入′b′'b'′b′,新建一个节点cnt=3,len[3]=len[last]+1=2cnt=3,len[3]=len[last]+1=2cnt=3,len[3]=len[last]+1=2
    从lastlastlast开始跳后缀链接
    222没有′b′'b'′b′边,新建一条并指向333,跳后缀链接到111
    111没有′b′'b'′b′边,新建一条并指向333
    此时已经到了根节点,333的后缀链接只能指向111,last=3last=3last=3

    Ⅳ 再加入′a′'a'′a′,新建一个节点cnt=4,len[4]=len[last]+1=3cnt=4,len[4]=len[last]+1=3cnt=4,len[4]=len[last]+1=3
    从lastlastlast开始跳后缀链接
    333没有′a′'a'′a′边,新建一条并指向444,跳后缀链接到111
    111有一条指向222的′a′'a'′a′边,满足len[2]=len[1]+1len[2]=len[1]+1len[2]=len[1]+1,则直接将444后缀链接指向222
    结束,last=4last=4last=4

    Ⅴ 再加入′b′'b'′b′,新建一个节点cnt=5,len[5]=len[last]+1=4cnt=5,len[5]=len[last]+1=4cnt=5,len[5]=len[last]+1=4
    从lastlastlast开始跳后缀链接
    444没有′b′'b'′b′边,新建一条并指向555,跳后缀链接到222
    222有一条指向333的′b′'b'′b′边,满足len[3]=len[2]+1len[3]=len[2]+1len[3]=len[2]+1,直接将555后缀链接指向333
    结束,last=5last=5last=5

    Ⅵ 加入新′c′'c'′c′,新建一个节点cnt=6,len[6]=len[last]+1=5cnt=6,len[6]=len[last]+1=5cnt=6,len[6]=len[last]+1=5
    从lastlastlast开始跳后缀链接
    555没有′c′'c'′c′边,新建一条并指向666,跳后缀链接到333
    333没有′c′'c'′c′边,新建一条并指向666,跳后缀链接到111
    111没有′c′'c'′c′边,新建一条并指向666
    此时已到根节点,666只能链接111,last=6last=6last=6结束
    这就是进阶版了,没有涉及到最终版的点复制
    最后让我们一起携手走进最终版的后缀自动机构造

  • e.g.3e.g.3e.g.3,构建cababcababcabab的后缀自动机
    Ⅰ 创造新源点,last=1,cnt=1last=1,cnt=1last=1,cnt=1

    Ⅱ 加入′c′'c'′c′,新建一个节点cnt=2,len[2]=len[last]+1=1cnt=2,len[2]=len[last]+1=1cnt=2,len[2]=len[last]+1=1
    从lastlastlast开始跳后缀链接
    111没有′c′'c'′c′边,新建一条并指向222
    此时已到根节点,222只能链接1,last=21,last=21,last=2

    Ⅲ 加入′a′'a'′a′,新建一个节点cnt=3,len[3]=len[last]+1=2cnt=3,len[3]=len[last]+1=2cnt=3,len[3]=len[last]+1=2
    从lastlastlast开始跳后缀链接
    222没有′a′'a'′a′边,新建一条并指向333,跳后缀链接到111
    111没有′a′'a'′a′边,新建一条并指向333
    此时已到根节点,333只能链接1,last=31,last=31,last=3

    Ⅳ 加入′b′'b'′b′,新建一个节点cnt=4,len[4]=len[last]+1=3cnt=4,len[4]=len[last]+1=3cnt=4,len[4]=len[last]+1=3
    从lastlastlast开始跳后缀链接
    333没有′b′'b'′b′边,新建一条并指向444,跳后缀链接到111
    111没有′a′'a'′a′边,新建一条并指向444
    此时已到根节点,444只能链接1,last=41,last=41,last=4

    Ⅴ 加入′a′'a'′a′,新建一个节点cnt=5,len[5]=len[last]+1=4cnt=5,len[5]=len[last]+1=4cnt=5,len[5]=len[last]+1=4
    从lastlastlast开始跳后缀链接
    444没有′a′'a'′a′边,新建一条并指向555,跳后缀链接到111
    111有′a′'a'′a′边,指向333,但是!!!len[3]≠len[1]+1len[3]≠len[1]+1len[3]​=len[1]+1,不能像进阶版直接链接,这里必须要点复制
    新建一个333的分身节点cnt=6cnt=6cnt=6
    333的所有信息(出入边)除了原字符串间的边(图中黑色边)全部修改为分点666的边,直接覆盖
    并且666成为333的直接后缀链接,替代111
    len[6]=len[1]+1=1len[6]=len[1]+1=1len[6]=len[1]+1=1
    相当于666做了1,31,31,3后缀链之间的承接点,保证了每一条边上lenlenlen只会带来+1+1+1的影响
    555直接链接666后结束,last=5last=5last=5

    Ⅵ 加入′b′'b'′b′,新建节点cnt=7cnt=7cnt=7
    从lastlastlast开始跳后缀链接
    555没有′b′'b'′b′边,新建一条指向777,跳后缀链接到666
    666有一条′b′'b'′b′边,指向444,判断len[4]≠len[6]+1len[4]≠len[6]+1len[4]​=len[6]+1

    再次执行复制操作
    新建一个444的分身节点cnt=8cnt=8cnt=8
    444的所有信息(出入边)除了原字符串间的边(图中黑色边)全部修改为分点888的边,直接进行覆盖
    888成为444的直接后缀链接,len[8]=len[6]+1=2len[8]=len[6]+1=2len[8]=len[6]+1=2
    777直接链接888后结束,last=7last=7last=7


len[x]len[x]len[x]复制点的lenlenlen不等于被复制点的原后缀链接的len+1len+1len+1,而是谁触发的len+1len+1len+1


模板

struct node {int len; //长度int fa; //后缀链接int son[maxc]; //字符集大小
}t[maxn];

模拟从主链的前一个开始跳后缀链接,并对于链接上的没有该字符边的每一个点都连出一条新字符边

while( pre && ! t[pre].son[c] ) t[pre].son[c] = now, pre = t[pre].fa;

跳到根,代表这是首个出现的字符,他只能链接最初的根节点了

if( ! pre ) t[now].fa = 1;

否则,如果路上找到了,满足lenlenlen的关系,直接后缀链接指过去即可

int u = t[pre].son[c];
if( t[u].len == t[pre].len + 1 ) t[now].fa = u;

复制该点,并进行有关该点的所有信息重改
①原点连出的点,新点也要连出
②连入原点的点,变成连入新点
③原点和新点间也需建立联系,新点是原点的后缀链接

else {int v = ++ tot;t[v] = t[u];//利用结构体巧妙将原点连出的点进行复制t[v].len = t[pre].len + 1;//由谁触发 len就是触发点len+1t[u].fa = t[now].fa = v;//原点与复制点与新建点的关系while( pre && t[pre].son[c] == u ) t[pre].son[c] = v, pre = t[pre].fa;//暴力复制修改连入原点的点
}

习题

洛谷后缀自动机模板题

#include <cstdio>
#include <vector>
#include <cstring>
using namespace std;
#define maxn 2000005
vector < int > G[maxn];
struct node {int fa, len;int son[30];
}t[maxn];
char s[maxn];
int last = 1, tot = 1;
long long ans;
int siz[maxn];void insert( int c ) {int pre = last, now = last = ++ tot;siz[tot] = 1;t[now].len = t[pre].len + 1;while( pre && ! t[pre].son[c] ) t[pre].son[c] = now, pre = t[pre].fa;if( ! pre ) t[now].fa = 1;else {int u = t[pre].son[c];if( t[u].len == t[pre].len + 1 ) t[now].fa = u;else {int v = ++ tot;t[v] = t[u];t[v].len = t[pre].len + 1;t[u].fa = t[now].fa = v;while( pre && t[pre].son[c] == u ) t[pre].son[c] = v, pre = t[pre].fa;}}
}void dfs( int u ) {for( int i = 0;i < G[u].size();i ++ ) {int v = G[u][i];dfs( v );siz[u] += siz[v];}if( siz[u] != 1 ) ans = max( ans, 1ll * siz[u] * t[u].len );
}int main() {scanf( "%s", s );int len = strlen( s );for( int i = 0;i < len;i ++ ) insert( s[i] - 'a' );  for( int i = 2;i <= tot;i ++ ) G[t[i].fa].push_back( i );dfs( 1 );printf( "%lld", ans );return 0;
}

品酒大会

#include <cstdio>
#include <vector>
#include <cstring>
#include <iostream>
using namespace std;
#define inf 0x7f7f7f7f
#define int long long
#define maxn 600005
struct node {int len, fa;int son[30];
}t[maxn];
vector < int > G[maxn];
int last = 1, cnt = 1, n;
char s[maxn];
int a[maxn], f[maxn], tot[maxn], siz[maxn], maxx[maxn], minn[maxn];void insert( int x, int w ) {int pre = last, now = last = ++ cnt;siz[now] = 1, t[now].len = t[pre].len + 1;maxx[now] = minn[now] = w;while( pre && ! t[pre].son[x] ) t[pre].son[x] = now, pre = t[pre].fa;if( ! pre ) t[now].fa = 1;else {int u = t[pre].son[x];if( t[u].len == t[pre].len + 1 ) t[now].fa = u;else {int v = ++ cnt;maxx[v] = -inf, minn[v] = inf;t[v] = t[u];t[v].len = t[pre].len + 1;t[u].fa = t[now].fa = v;while( pre && t[pre].son[x] == u ) t[pre].son[x] = v, pre = t[pre].fa;}}
}bool check( int u ) {return maxx[u] != -inf && minn[u] != inf;
}void dfs( int u ) {for( int i = 0;i < G[u].size();i ++ ) {int v = G[u][i];dfs( v );tot[t[u].len] += siz[u] * siz[v];siz[u] += siz[v];if( check( u ) )f[t[u].len] = max( f[t[u].len], max( maxx[u] * maxx[v], minn[u] * minn[v] ) );maxx[u] = max( maxx[u], maxx[v] );minn[u] = min( minn[u], minn[v] );}
}signed main() {memset( f, -0x7f, sizeof( f ) );scanf( "%d %s", &n, s + 1 );for( int i = 1;i <= n;i ++ )scanf( "%lld", &a[i] );for( int i = n;i;i -- ) insert( s[i] - 'a', a[i] );   for( int i = 2;i <= cnt;i ++ ) G[t[i].fa].push_back( i );dfs( 1 );for( int i = n - 1;~ i;i -- ) tot[i] += tot[i + 1], f[i] = max( f[i], f[i + 1] );for( int i = 0;i < n;i ++ )printf( "%lld %lld\n", tot[i], ( tot[i] ? f[i] : 0 ) );return 0;
}

[HEOI2015]最短不公共子串

#include <queue>
#include <cstdio>
#include <cstring>
using namespace std;
#define maxn 5000
char a[maxn], b[maxn];struct SAM {struct node {int len, fa;int son[30];}t[maxn];int last, cnt;SAM() {last = cnt = 1;}void insert( int x ) {int pre = last, now = last = ++ cnt;t[now].len = t[pre].len + 1;while( pre && ! t[pre].son[x] ) t[pre].son[x] = now, pre = t[pre].fa;if( ! pre ) t[now].fa = 1;else {int u = t[pre].son[x];if( t[u].len == t[pre].len + 1 ) t[now].fa = u;else {int v = ++ cnt;t[v] = t[u];t[v].len = t[pre].len + 1;t[u].fa = t[now].fa = v;while( pre && t[pre].son[x] == u ) t[pre].son[x] = v, pre = t[pre].fa;}}}}SamA, SamB;struct SEQ {int nxt[maxn][30], last[30];SEQ() {memset( nxt, 0, sizeof( nxt ) );memset( last, 0, sizeof( last ) );}void build( int n, char *s ) {for( int i = n;~ i;i -- ) {for( int j = 0;j < 26;j ++ )if( last[j] ) nxt[i + 1][j] = last[j];if( i ) last[s[i] - 'a'] = i + 1;}}}SeqA, SeqB;struct node {int x, y, dep;node(){}node( int X, int Y, int Dep ) {x = X, y = Y, dep = Dep;}
};
queue < node > q;
bool vis[maxn][maxn];void init() {memset( vis, 0, sizeof( vis ) );while( ! q.empty() ) q.pop();vis[1][1] = 1, q.push( node( 1, 1, 0 ) );
}int bfs1() {init();while( ! q.empty() ) {node now = q.front(); q.pop();for( int i = 0;i < 26;i ++ ) {int sonA = SamA.t[now.x].son[i];int sonB = SamB.t[now.y].son[i];if( vis[sonA][sonB] ) continue;else if( sonA && ! sonB ) return now.dep + 1;else if( sonA && sonB ) {vis[sonA][sonB] = 1;q.push( node( sonA, sonB, now.dep + 1 ) );}}}return -1;
}int bfs2() {init();while( ! q.empty() ) {node now = q.front(); q.pop();for( int i = 0;i < 26;i ++ ) {int sonA = SamA.t[now.x].son[i];int sonB = SeqB.nxt[now.y][i];if( vis[sonA][sonB] ) continue;else if( sonA && ! sonB ) return now.dep + 1;else if( sonA && sonB ) {vis[sonA][sonB] = 1;q.push( node( sonA, sonB, now.dep + 1 ) );}}}return -1;
}int bfs3() {init();while( ! q.empty() ) {node now = q.front(); q.pop();for( int i = 0;i < 26;i ++ ) {int sonA = SeqA.nxt[now.x][i];int sonB = SamB.t[now.y].son[i];if( vis[sonA][sonB] ) continue;else if( sonA && ! sonB ) return now.dep + 1;else if( sonA && sonB ) {vis[sonA][sonB] = 1;q.push( node( sonA, sonB, now.dep + 1 ) );}}}return -1;
}int bfs4() {init();while( ! q.empty() ) {node now = q.front(); q.pop();for( int i = 0;i < 26;i ++ ) {int sonA = SeqA.nxt[now.x][i];int sonB = SeqB.nxt[now.y][i];if( vis[sonA][sonB] ) continue;else if( sonA && ! sonB ) return now.dep + 1;else if( sonA && sonB ) {vis[sonA][sonB] = 1;q.push( node( sonA, sonB, now.dep + 1 ) );}}}return -1;
}int main() {scanf( "%s %s", a + 1, b + 1 );int lena = strlen( a + 1 ), lenb = strlen( b + 1 );for( int i = 1;i <= lena;i ++ )SamA.insert( a[i] - 'a' );for( int i = 1;i <= lenb;i ++ )SamB.insert( b[i] - 'a' );SeqA.build( lena, a );SeqB.build( lenb, b );printf( "%d\n%d\n%d\n%d\n", bfs1(), bfs2(), bfs3(), bfs4() );return 0;
}

字符串

这题运用的思想主要是广义后缀自动机,即将多个字符串建在一个后缀自动机上
其实并没有什么新颖之处,只需在扩展的时候带一个这个字符属于哪个字符串的编号即可

假设已经建好了自动机,接下来考虑两个长度为kkk的子串之间如何一一对应修改
这个时候如果将其放到parenttreeparent\ treeparent tree上考虑的话,就简单了

其实可以猜想一下,刚开始我就想到了虚树的性质,即相邻两两配对
不难证明,的确应该相邻两个不同属类的子串配对

前缀i,ji,ji,j的最长公共后缀=parenttree=parent\ tree=parent tree上前缀i,ji,ji,j分别指向的点u,vu,vu,v的lcalcalca反映在后缀自动机上的节点代表的最长子串

也就是最后变成深搜一棵树的模样,记得特判可能lcalcalca代表的最长子串长度≥k\ge k≥k
此时是不需要代价的

#include <cstdio>
#include <vector>
#include <iostream>
#include <algorithm>
using namespace std;
#define maxn 600005
struct node {int len, fa;int son[30];
}t[maxn];
vector < int > G[maxn];
int n, k, last = 1, cnt = 1;
long long ans;
char a[maxn], b[maxn];
int type[maxn];
int tot[maxn][3];void insert( int x, int s, int pos ) {int pre = last, now = last = ++ cnt;t[now].len = t[pre].len + 1;while( pre && ! t[pre].son[x] ) t[pre].son[x] = now, pre = t[pre].fa;if( ! pre ) t[now].fa = 1;else {int u = t[pre].son[x];   if( t[u].len == t[pre].len + 1 ) t[now].fa = u;else {int v = ++ cnt;t[v] = t[u];t[v].len = t[pre].len + 1;t[u].fa = t[now].fa = v;while( pre && t[pre].son[x] == u ) t[pre].son[x] = v, pre = t[pre].fa;}}if( pos >= k ) type[now] = s;
}void dfs( int u ) {tot[u][type[u]] ++;for( int i = 0;i < G[u].size();i ++ ) {int v = G[u][i];dfs( v );tot[u][1] += tot[v][1];tot[u][2] += tot[v][2];}if( tot[u][1] >= tot[u][2] ) {int x = max( 0, k - t[u].len );ans += 1ll * x * tot[u][2];tot[u][1] -= tot[u][2];tot[u][2] = 0;}else {int x = max( 0, k - t[u].len );ans += 1ll * x * tot[u][1];tot[u][2] -= tot[u][1];tot[u][1] = 0;}
}int main() {scanf( "%d %d %s %s", &n, &k, a + 1, b + 1 );reverse( a + 1, a + n + 1 );reverse( b + 1, b + n + 1 );for( int i = 1;i <= n;i ++ ) insert( a[i] - 'a', 1, i );for( int i = 1;i <= n;i ++ ) insert( b[i] - 'a', 2, i );for( int i = 2;i <= cnt;i ++ ) G[t[i].fa].push_back( i );dfs( 1 );printf( "%lld", ans );return 0;
}

后缀自动机(SAM)构造实现过程演示+习题集锦相关推荐

  1. 后缀自动机(SAM)讲解 + Luogu p3804【模板】后缀自动机 (SAM)

    本文求节点子串长度最小值有点问题,现已修改. SAM 后缀自动机可以存储某一个字符串的所有子串. 一.概念 下图是一个 字符串 "aababa" 的 后缀自动机. 上图中的 黑色边 ...

  2. JZOJ4025. 【佛山市选2015】找回密码(后缀自动机SAM)

    题目描述 Description Kevin是一个热爱字符串的小孩.有一天,他把自己的微信登录密码给忘记了,万般无奈之下只好点"找回密码". 这时候,网页上出现了当初设定的密保问题 ...

  3. 后缀自动机SAM详解

    用一个DFA来识别一个串(比如aabab)的所有后缀,要怎么做呢 最简单的办法,把所有后缀看作要保存的单词,画一棵 trie树,像这样: 点很多很麻烦复杂度也很高 我们给这个DFA按我们的需求合并化简 ...

  4. [hdu4416 Good Article Good sentence]后缀自动机SAM

    题意:给出串A和串集合B={B1,B2,...,Bn},求串A的所有不同子串中不是B中任一串的子串的数目. 思路:把A和B中所有字符串依次拼接在一起,然后构造后缀自动机,计算每个状态的R集合元素的最大 ...

  5. 多校冲刺NOIP模拟6 - 游戏——矩阵乘法、后缀自动机SAM

    此题不提供链接 题目描述 前言 好久没用SAM了.我记得上次用SAM做题还是在上次. 题解 每一种长度的总方案是确定的,所以我们只需要求出赢的方案数.平局方案数即可. 做法其实和官方正解区别不大,官方 ...

  6. P3804 【模板】后缀自动机 (SAM)

    传送门 文章目录 题意: 思路: 题意: 给你一个字符串sss,让你求sss中出现次数不为111的子串出现次数乘上该字串长度最大值. ∣s∣≤1e6|s|\le 1e6∣s∣≤1e6 思路: 没学明白 ...

  7. 后缀自动机线性构造方法

    前置(后缀自动机SAM基本概念):https://blog.csdn.net/Jaihk662/article/details/82823251 来源:http://hihocoder.com/pro ...

  8. 后缀自动机 AC自动机

    trie树可遍历出所有无重复后缀,通过后缀遍历前缀可得到所有子串:后缀链接把所有后缀相同的状态(以当前节点为endpos的子串)连接起来,便有了类似KMP的next数组的性质.             ...

  9. 后缀自动机Suffix Links的应用

    前置: 后缀自动机SAM基本概念:https://blog.csdn.net/Jaihk662/article/details/82823251 后缀自动机线性构造方法:https://blog.cs ...

最新文章

  1. 最先进的图像分类算法:FixEfficientNet-L2
  2. linux命令行参数含空格,linux-具有命令行参数和空格的Perl脚本
  3. 学习《html5.css3.0》网页布局和样式精粹(第二天)
  4. R语言入门4---R语言流程控制
  5. java面向对象语言_Java到底是不是一种纯面向对象语言?
  6. C++一天一个程序(三)
  7. Unity3d 屏幕空间人体皮肤知觉渲染次表面散射Screen-Space Perceptual Rendering Subsurface Scattering of Human Skin...
  8. 「动手学深度学习」在B站火到没谁,加这个免费实操平台,妥妥天花板
  9. php表单转json对象,form表单转Json提交的方法(推荐)
  10. MyEclipse开启Jquery智能提示
  11. MATLAB函数拟合指令,MATLAB拟合函数使用说明
  12. Android仿人人客户端(v5.7.1)——新鲜事之分享照片
  13. outlook设置京东邮箱
  14. 熵(Entropy):机器学习
  15. Python基础了解 python自带IDLE编译
  16. bflvphnlrffbdbv
  17. ABB机器人6.13版手册下载
  18. Tensorflow 模型文件结构、模型中Tensor查看
  19. 在oracle 中编写一个程序,用VC 开 发 基 于ORACLE 数 据 库 应 用 程 序 的 两 种 方 法...
  20. raw图片处理软件:DxO PhotoLab for Mac

热门文章

  1. Python项目可以有多大?最多可以有多少行代码?
  2. Boosting集合算法详解(一)
  3. python柱状图挨在一起_echarts多个柱状图展示问题(bar都挤到一起了)
  4. matlab 抽样判决代码,matlab抽样判决器
  5. 面试问外观模式???这不就是设计模式里面的吗?我给你上一课吧,面试官
  6. linux删除grid数据文件,MongoDB进阶系列(13)——GridFS大文件的添加、获取、查看、删除...
  7. wordpress home.php,WordPress主题通过function.php来加载js和css文件
  8. 小肚皮最新版本_小肚皮官方版下载_小肚皮app - Win7旗舰版
  9. c语言管理系统信息以文件保存,求大神给一份能用的c语言的学籍管理系统:且能进行文件保存...
  10. 内网通mac能用吗_纯干货!小容量Mac装外置硬盘Windows系统最完美的方案!(多图)...