各种模板总结
2016-09-26 13:10
246 查看
数据结构
线段树
树链剖分 √
Treap
Splay
左偏堆
划分树 待添加
字符串
KMP
MANACHER
字典树
01字典树 √
AC自动机 √
后缀数组 √
回文树 √
数论
矩阵快速幂 待添加
图论
最短路(Dijkastra)待添加
最短路(Floyd)待添加
最短路(SPFA)待添加
最小生成树(Prim) 待添加
最小生成树(Kurskal) 待添加
计算几何
扫描线 √
其他
大整数模板 √
快速输入模板 (整数) √
快速输入模板 (实数) √
1~MOD的逆元 √
-
树链剖分 √
Treap
Splay
01字典树 √
KMP
AC自动机 √
MANACHER
后缀数组 √
[b]回文树 √
字典树
线段树
左偏堆
[b]大整数 √
快速输入 (整数) √
快速输入 (实数) √
扫描线 √
1~MOD的逆元 √
线段树
树链剖分 √
Treap
Splay
左偏堆
划分树 待添加
字符串
KMP
MANACHER
字典树
01字典树 √
AC自动机 √
后缀数组 √
回文树 √
数论
矩阵快速幂 待添加
图论
最短路(Dijkastra)待添加
最短路(Floyd)待添加
最短路(SPFA)待添加
最小生成树(Prim) 待添加
最小生成树(Kurskal) 待添加
计算几何
扫描线 √
其他
大整数模板 √
快速输入模板 (整数) √
快速输入模板 (实数) √
1~MOD的逆元 √
-
树链剖分 √
const int maxn = 100000 + 5; //树中节点个数 //边集 struct Edge{ int v,pre,c; }Es[maxn * 2]; int head[maxn],TOT_EDGE; void INIT_EDGE(){ //边集初始化 memset(head,-1,sizeof head); TOT_EDGE = 0; } void ADD_EDGE(int u,int v,int c){ //添加边 Es[TOT_EDGE].v = v; Es[TOT_EDGE].c = c; Es[TOT_EDGE].pre = head[u]; head[u] = TOT_EDGE++; } /**树链剖分部分*/ /** ** son: 节点重儿子 ** fa: 节点父节点 ** dep: 节点在树中深度 ** size: 节点子树的大小 ** top: 节点在重链中的深度最低节点(最高节点) ** tid: 节点编号(hash值) ** RANK: RANK[v]编号为v的是第RANK[v]节点 ** SegSize:用于编号的迭代辅助变量,最小编号为SegSize的初始值 */ int son[maxn],fa[maxn],dep[maxn],size[maxn]; int top[maxn],tid[maxn],RANK[maxn],SegSize; int DFS(int rt){ dep[rt] = dep[fa[rt]] + 1; son[rt] = 0; size[rt] = 1; for(int i = head[rt];~i;i = Es[i].pre){ int v = Es[i].v; if(v != fa[rt]){ fa[v] = rt; size[rt] += DFS(v); if(size[son[rt]] < size[v]) son[rt] = v; } } return size[rt]; } void Split(int rt,int tp){ top[rt] = tp; tid[rt] = ++SegSize; RANK[tid[rt]] = rt; if(son[rt]){ Split(son[rt],tp); for(int i = head[rt];~i;i = Es[i].pre){ int v = Es[i].v; if(v != fa[rt] && v != son[rt]) Split(v,v); } } } void TreeLineSplit(){ //开始剖分 dep[0] = 0; size[0] = 0; fa[1] = 0; DFS(1); SegSize = -1; Split(1,1); }
Treap
/** ** ch:节点的孩子节点 ** fa:夫节点 ** fix;优先级 ** size:当前子树的大小 ** tot:节点个数(包括sroot) ** sroot:超级根节点 ** key:节点的键值 */ const int maxn = 15000 + 50,INF = 0x7fffffff; int ch[maxn][2],fa[maxn],fix[maxn],size[maxn]; int tot,root,sroot; int key[maxn]; /** ** Treap初始化 */ void Treap_Init(){ tot = 1; root = sroot = 0; ch[sroot][0] = ch[sroot][1] = 0; fa[sroot] = 0; size[sroot] = 0; fix[sroot] = key[sroot] = INF; } /** ** 新建一个父节点为FA,键值为k的节点,返回节点编号 ** */ int NewNode(int FA,int k){ ch[tot][0] = ch[tot][1] = 0; fa[tot] = FA; size[tot] = 1; fix[tot] = rand(); key[tot] = k; return tot++; } /** ** 更新rt的size信息 */ void PushUp(int rt){ size[rt] = size[ch[rt][0]] + size[ch[rt][1]] + 1; if(rt == sroot) size[rt] = 0;} /** ** 旋转操作 ** kind: 0.表示rt为fa[rt]的左孩子 进行右旋操作 zig ** kind: 1.表示rt为fa[rt]的右孩子 进行左旋操作 zag */ void rotate(int rt,int kind){ int prt = fa[rt]; ch[prt][kind] = ch[rt][!kind];fa[ch[rt][!kind]] = prt; ch[fa[prt]][ch[fa[prt]][1] == prt] = rt;fa[rt] = fa[prt]; ch[rt][!kind] = prt;fa[prt] = rt; PushUp(prt);PushUp(rt); } /** ** 在根为rt的树中插入键值为K的元素 这里可以重复键值 */ void Insert(int rt,int k){ while(ch[rt][k >= key[rt]]) rt = ch[rt][k >= key[rt]]; ch[rt][k >= key[rt]] = NewNode(rt,k); rt = ch[rt][k >= key[rt]]; while(fa[rt] != sroot && fix[rt] > fix[fa[rt]]) rotate(rt,ch[fa[rt]][1] == rt); if(fa[rt] == sroot) root = rt; while(fa[rt] != sroot){ rt = fa[rt];PushUp(rt); } } /** ** 删除键值为k的节点,使用前要保证一定有键值为k的节点 */ void Delete(int rt,int k){ if(key[rt] == k){ if(ch[rt][0] && ch[rt][1]){ int nrt = ch[rt][0]; if(fix[nrt] < fix[ch[rt][1]]) nrt = ch[rt][1]; rotate(nrt,ch[rt][1] == nrt); Delete(rt,k);PushUp(nrt); } else{ int nrt = ch[rt][0]; if(nrt == sroot) nrt = ch[rt][1]; ch[fa[rt]][ch[fa[rt]][1] == rt] = nrt;fa[nrt] = fa[rt]; } } else{ Delete(ch[rt][k >= key[rt]],k); PushUp(rt); } } /** ** 在rt的树中查找键值第k小的节点 返回节点编号 */ int Search(int rt,int k){ if(k <= size[ch[rt][0]]) return Search(ch[rt][0],k); else if(k > size[ch[rt][0]] + 1) return Search(ch[rt][1],k - 1 - size[ch[rt][0]]); else return rt; } /** ** 查找键值为k的节点在树中是第几小的 */ int getRank(int rt,int k){ if(rt == sroot) return 0; if(k >= key[rt]) return size[ch[rt][0]] + 1 + getRank(ch[rt][1],k); else return getRank(ch[rt][0],k); }
Splay
/** ---- SPLAY ---- **/ /** ch 边 ** fa 父节点 ** size 子树大小 ** key 关键字大小 ** tot 总共节点的个数 ** root 当前的树根 ** sroot 超级根节点 **/ int ch[maxn][2],fa[maxn],size[maxn]; int key[maxn],pos[maxn]; int tot,root,sroot; /** 初始化 */ void Splay_Init(){ tot = 1; root = sroot = 0; ch[0][0] = ch[0][1] = 0; fa[0] = 0; key[0] = INF; size[0] = 0; } /** 新建一个节点 */ int NewNode(int FA,int k,int p){ ch[tot][0] = ch[tot][1] = 0; fa[tot] = FA; size[tot] = 1; key[tot] = k,pos[tot] = p; return tot++; } /** 更新当前子树的大小 和 根节点保留的信息 */ void PushUp(int rt){size[rt] = 1 + size[ch[rt][0]] + size[ch[rt][1]];} /** 节点的旋转操作 ** kind 0 表示rt为fa[rt]的左孩子 ** kind 1 表示rt为fa[rt]的右孩子 ** kind 0 进行zig 1 进行zag */ void rotate(int rt,int kind){ int prt = fa[rt]; ch[prt][kind] = ch[rt][!kind];fa[ch[rt][!kind]] = prt; ch[fa[prt]][ch[fa[prt]][1] == prt] = rt;fa[rt] = fa[prt]; ch[rt][!kind] = prt;fa[prt] = rt; PushUp(prt);PushUp(rt); } /** 将rt节点 伸展至goal的孩子节点 */ void Splay(int rt,int goal){ while(fa[rt] != goal){ if(fa[fa[rt]] == goal) rotate(rt,ch[fa[rt]][1] == rt); else{ int prt = fa[rt],kind = (ch[fa[prt]][1] == prt); if(ch[prt][kind] == rt) rotate(rt,kind),rotate(rt,kind); else rotate(rt,!kind),rotate(rt,kind); } } if(fa[rt] == sroot) root = rt; } /** 在根为rt的树内,插入关键字为k的节点 */ void Insert(int rt,int k,int p){ while(ch[rt][k > key[rt]]) rt = ch[rt][k > key[rt]]; rt = (ch[rt][k > key[rt]] = NewNode(rt,k,p)); Splay(rt,sroot); } /** 在根为rt的树内,查找关键字为k的节点 */ int Find(int rt,int k){ while(ch[rt][k >= key[rt]]) if(k == key[rt]) return rt; else rt = ch[rt][k >= key[rt]]; return sroot; } /** 查找关键字为k 的前驱 */ int Find_Pre(int rt,int k){ rt = Find(rt,k); Splay(rt,sroot); if(ch[rt][0] == sroot) return sroot; else rt = ch[rt][0]; while(ch[rt][1]) rt = ch[rt][1]; return rt; } /** 查找关键字为k 的后继 */ int Find_Next(int rt,int k){ rt = Find(rt,k); Splay(rt,sroot); if(ch[rt][1] == sroot) return sroot; else rt = ch[rt][1]; while(ch[rt][0]) rt = ch[rt][0]; return rt; }
01字典树 √
const int maxn = 100000 + 5; //集合中的数字个数 typedef long long LL; int ch[32 * maxn][2]; //节点的边信息 LL value[32 * maxn]; //节点存储的值 int node_cnt; //树中当前节点个数 inline void init(){ //树清空 node_cnt = 1; memset(ch[0],0,sizeof(ch)); } inline void Insert(LL x){ //在字典树中插入 X //和一般字典树的操作相同 将X的二进制插入到字典树中 int cur = 0; for(int i = 32;i >= 0;--i){ int idx = (x >> i) & 1; if(!ch[cur][idx]){ memset(ch[node_cnt],0,sizeof(ch[node_cnt])); ch[cur][idx] = node_cnt; value[node_cnt++] = 0; } cur = ch[cur][idx]; } value[cur] = x; //最后的节点插入value } inline LL Query(LL x){ //在字典树中查找和X异或的最大值的元素Y 返回Y的值 int cur = 0; for(int i = 32;i >= 0;--i){ int idx = (x >> i) & 1; if(ch[cur][idx ^ 1]) cur = ch[cur][idx ^ 1]; else cur = ch[cur][idx]; } return value[cur]; }
KMP
const int maxn = 100; char s[maxn],p[maxn]; int fail[maxn]; /* p为模式串 ** f为保存失配边的数组 ** */ void getFail(char* p,int* f){ int m = strlen(p); f[0] = 0; f[1] = 0; for(int i = 1;i < m;++i){ int j = f[i]; while(j && p[i] != p[j]) j = f[j]; f[i + 1] = p[i] == p[j] ? j + 1 : 0; } } /* ** s为文本串 p为模式串,fail保存失配边 ** 匹配成功返回true ** 失败返回false */ bool Match(char* s,char* p,int* fail){ getFail(p,fail);//得到fail数值 int m = strlen(p),n = strlen(s); int i = 0, j = 0; while(i < n){ while(i < n && j < m && s[i] == s[j]){//新一轮匹配 i++,j++; } if(j == m) return true;//匹配成功 j--; while(j && p[j] != s[i]) j = fail[j];//根据fail跳转 } return false; }
AC自动机 √
const int maxn = 10000 * 50 + 50,sigma_size = 26; /** AC_AUTOMATON */ int ch[maxn][sigma_size],fail[maxn],tot; int value[maxn]; /** 初始化 */ void Init(){ memset(ch[0],0,sizeof ch[0]); tot = 1; fail[0] = -1;value[0] = 0; } /** 插入字符串 s */ void Insert(char* s){ int idx,cur = 0; while( *s ){ idx = *s - 'a'; if(ch[cur][idx] == 0){ memset(ch[tot],0,sizeof ch[tot]); fail[tot] = 0; value[tot] = 0; ch[cur][idx] = tot++; } cur = ch[cur][idx]; s++; } value[cur]++; } /** GetFail */ void GetFail(){ queue<int> Q; Q.push(0); fail[0] = -1; int cur,idx,f; while(!Q.empty()){ cur = Q.front();Q.pop(); for(int i = 0;i < sigma_size;++i){ if(ch[cur][i]){ f = fail[cur]; while(f != -1 && ch[f][i] == 0) f = fail[f]; fail[ch[cur][i]] = (f == -1) ? 0 : ch[f][i]; Q.push(ch[cur][i]); } else{ f = fail[cur]; ch[cur][i] = (f == -1) ? 0 : ch[f][i]; } } } } /** 以上具有通用性 */ /** 匹配 */ int Search(char *s){ int cur = 0,idx,ret = 0,tmp; while(*s){ idx = *s - 'a'; tmp = cur = ch[cur][idx]; if(value[tmp]) while(tmp){ ret += value[tmp];value[tmp] = 0; tmp = fail[tmp]; } s++; } return ret; }
MANACHER
const int maxn = 500; int dis[maxn]; char str1[maxn],str2[maxn]; int get_dis(){ int len = strlen(str1); str2[0] = '$'; char* str_a = str2 + 1; for(int i = 0;i <= len;++i){ str_a[i * 2] = '#'; str_a[i * 2 + 1] = str1[i]; } int id = 0, mx = 1,len2 = strlen(str2); for(int i = 1;i < len2;++i){ if(mx > i){ dis[i] = (dis[id * 2 - i] < (mx - i) ? dis[2 * id - i] : (mx - i)); } else dis[i] = 1; while(str2[i - dis[i]] == str2[i + dis[i]]) dis[i]++; if(i + dis[i] > mx){ mx = i + dis[i]; id = i; } } return len2; }
后缀数组 √
int wa[maxn],wb[maxn],wv[maxn],ws[maxn]; int cmp(int *r,int a,int b,int l) {return r[a]==r&&r[a+l]==r[b+l];} void da(int *r,int *sa,int n,int m) { int i,j,p,*x=wa,*y=wb,*t; for(i=0;i<m;i++) ws[i]=0; for(i=0;i<n;i++) ws[x[i]=r[i]]++; for(i=1;i<m;i++) ws[i]+=ws[i-1]; for(i=n-1;i>=0;i--) sa[--ws[x[i]]]=i; for(j=1,p=1;p<n;j*=2,m=p) { for(p=0,i=n-j;i<n;i++) y[p++]=i; for(i=0;i<n;i++) if(sa[i]>=j) y[p++]=sa[i]-j; for(i=0;i<n;i++) wv[i]=x[y[i]]; for(i=0;i<m;i++) ws[i]=0; for(i=0;i<n;i++) ws[wv[i]]++; for(i=1;i<m;i++) ws[i]+=ws[i-1]; for(i=n-1;i>=0;i--) sa[--ws[wv[i]]]=y[i]; for(t=x,x=y,y=t,p=1,x[sa[0]]=0,i=1;i<n;i++) x[sa[i]]=cmp(y,sa[i-1],sa[i],j)?p-1:p++; } return; } int rank[maxn],height[maxn]; void calheight(int *r,int *sa,int n) { int i,j,k=0; for(i=1;i<=n;i++) rank[sa[i]]=i; for(i=0;i<n;height[rank[i++]]=k) for(k?k--:0,j=sa[rank[i]-1];r[i+k]==r[j+k];k++); return; }
[b]回文树 √
const int MAXN = 100005; struct node { int next[26]; //边 int len; //回文串长度 int sufflink; //后缀指针 int num; }; int len; char s[MAXN]; node tree[MAXN]; int num; // node 1 - root with len -1, node 2 - root with len 0 int suff; // max suffix palindrome long long ans; bool addLetter(int pos) { int cur = suff, curlen = 0; int let = s[pos] - 'a'; while (true) { curlen = tree[cur].len; //当前可能上一个回文串长度 if (pos - 1 - curlen >= 0 && s[pos - 1 - curlen] == s[pos]) //如果能形成行如XAX的回文串 break; cur = tree[cur].sufflink; //查找失败 找到更小的回文 } if (tree[cur].next[let]) { //这个节点已经存在 suff = tree[cur].next[let]; //更新最长前缀值 return false; } num++; suff = num; tree[num].len = tree[cur].len + 2; tree[cur].next[let] = num; //加一个节点 if (tree[num].len == 1) { //只有一个X tree[num].sufflink = 2; //指向空串 tree[num].num = 1; return true; } while (true) { cur = tree[cur].sufflink; curlen = tree[cur].len; if (pos - 1 - curlen >= 0 && s[pos - 1 - curlen] == s[pos]) { tree[num].sufflink = tree[cur].next[let]; break; } } tree[num].num = 1 + tree[tree[num].sufflink].num; return true; } void initTree() { num = 2; suff = 2; tree[1].len = -1; tree[1].sufflink = 1; tree[2].len = 0; tree[2].sufflink = 1; }
字典树
struct Trie{ /** * maxnode: Trie树中最多可能的节点个数 上限为字符串个数 * 最长长度 * sigma_size: 组成字符串的字符种类 * ch: 边 * value: 节点的值 * sz: Trie树的总节点个数 */ int ch[maxnode][sigma_size]; int value[maxnode]; int sz; int IDX(char c) {return c - 'a';} Trie(){ sz = 1; memset(ch[0],0,sizeof(ch[0])); } /** * 字符串s插入Trie中 值为V */ void Insert(char* s,int v){ int u = 0,len = strlen(s); for(int i = 0;i < len;++i){ int c = IDX(s[i]); if(!ch[u][c]){ memset(ch[sz],0,sizeof(ch[sz])); value[sz] = 0; ch[u][c] = sz++; } u = ch[u][c]; } value[u] = v; } /** * 查找字符串s 返回v */ int Search(char* s){ int cur = 0,idx; while(*s){ idx = IDX(*s); if(ch[cur][idx] == 0) return -1; cur = ch[cur][idx]; s++; } return value[cur]; } };
线段树
#include <bits/stdc++.h> using namespace std; /** 线段树模板 */ /** 以求区间和为例 */ #define lson rt << 1 , l ,mid #define rson rt << 1 | 1,mid + 1,r const int maxn = 50000 + 50; int v[maxn << 2],laze[maxn << 2]; int A[maxn]; // 向下Push laze标记 void PushDown(int rt,int l,int r){ if(laze[rt]){ int mid = l + r >> 1,lcnt = mid - l + 1,rcnt = r - mid; v[rt << 1] = v[rt << 1] + lcnt * laze[rt]; v[rt << 1 | 1] = v[rt << 1 | 1] + rcnt * laze[rt]; laze[rt << 1] += laze[rt];laze[rt << 1 | 1] += laze[rt]; laze[rt] = 0; } } //向上更新sum值 void PushUp(int rt){ v[rt] = v[rt << 1] + v[rt << 1 | 1]; } void Build(int rt,int l,int r){ if(l == r){ v[rt] = A[l];return; } int mid = l + r >> 1; Build(lson),Build(rson); laze[rt] = 0; PushUp(rt); } //将区间L,R 增加X void Update(int rt,int l,int r,int L,int R,int x){ if(L <= l && R >= r){ v[rt] += x * (r - l + 1); laze[rt] += x; return; } PushDown(rt,l,r); int mid = l + r >> 1; if(L <= mid) Update(lson,L,R,x); if(R > mid) Update(rson,L,R,x); PushUp(rt); } int Query(int rt,int l,int r,int L,int R){ if(L <= l && R >= r){ return v[rt]; } PushDown(rt,l,r); int mid = l + r >> 1; int ret = 0; if(L <= mid) ret += Query(lson,L,R); if(R > mid) ret += Query(rson,L,R); PushUp(rt); return ret; }
左偏堆
int key[maxn],dis[maxn],ch[maxn][2]; /**合并以a,b为堆顶的堆*/ int Merge(int a,int b){ if(!a) return b;if(!b) return a; if(key[a] < key) swap(a,b); ch[a][1] = Merge(ch[a][1],b); if(dis[ch[a][0]] < dis[ch[a][1]]) swap( ch[a][0],ch[a][1] ); if(ch[a][1] == 0) dis[a] = 0; else dis[a] = dis[ch[a][1]] + 1; return a; }
[b]大整数 √
struct BigInteger{ int A[25]; enum{MOD = 10000}; BigInteger(){memset(A, 0, sizeof(A)); A[0]=1;} void set(int x){memset(A, 0, sizeof(A)); A[0]=1; A[1]=x;} void print(){ printf("%d", A[A[0]]); for (int i=A[0]-1; i>0; i--){ if (A[i]==0){printf("0000"); continue;} for (int k=10; k*A[i]<MOD; k*=10) printf("0"); printf("%d", A[i]); } printf("\n"); } int& operator [] (int p) {return A[p];} const int& operator [] (int p) const {return A[p];} BigInteger operator + (const BigInteger& B){ BigInteger C; C[0]=max(A[0], B[0]); for (int i=1; i<=C[0]; i++) C[i]+=A[i]+B[i], C[i+1]+=C[i]/MOD, C[i]%=MOD; if (C[C[0]+1] > 0) C[0]++; return C; } BigInteger operator * (const BigInteger& B){ BigInteger C; C[0]=A[0]+B[0]; for (int i=1; i<=A[0]; i++) for (int j=1; j<=B[0]; j++){ C[i+j-1]+=A[i]*B[j], C[i+j]+=C[i+j-1]/MOD, C[i+j-1]%=MOD; } if (C[C[0]] == 0) C[0]--; return C; } };
快速输入 (整数) √
inline bool scan_d(int &num) { char in;bool IsN=false; in=getchar(); if(in==EOF) return false; while(in!='-'&&(in<'0'||in>'9')) in=getchar(); if(in=='-'){ IsN=true;num=0;} else num=in-'0'; while(in=getchar(),in>='0'&&in<='9'){ num*=10,num+=in-'0'; } if(IsN) num=-num; return true; }
快速输入 (实数) √
inline bool scan_lf(double &num) { char in;double Dec=0.1; bool IsN=false,IsD=false; in=getchar(); if(in==EOF) return false; while(in!='-'&&in!='.'&&(in<'0'||in>'9')) in=getchar(); if(in=='-'){IsN=true;num=0;} else if(in=='.'){IsD=true;num=0;} else num=in-'0'; if(!IsD){ while(in=getchar(),in>='0'&&in<='9'){ num*=10;num+=in-'0';} } if(in!='.'){ if(IsN) num=-num; return true; }else{ while(in=getchar(),in>='0'&&in<='9'){ num+=Dec*(in-'0');Dec*=0.1; } } if(IsN) num=-num; return true; }
扫描线 √
using namespace std; const int maxn = 100 + 5; const int TOT_SEG = maxn * 2; /** Seg ** l,r,h 分别为线段的左端点,右端点,高 ** f 标识上下边 */ struct Seg{ int f; double l,r,h; void set(double ll,double rr,double hh,int d){ l = ll,r = rr,h = hh,f = d; } }Segs[TOT_SEG]; bool cmp(const Seg& a,const Seg& b){ return a.h < b.h; } double AR[TOT_SEG]; /** 区间长度 */ map<double,int> POS; /** 将端点 HASH 到区间上 */ int FALG[TOT_SEG]; /** 区间被覆盖的次数 */ int Seg_CNT,HASH_SEG_CNT; void SEG_HASH(){ POS.clear();HASH_SEG_CNT = 2; sort(Segs + 1,Segs + Seg_CNT,cmp); sort(AR + 1,AR + Seg_CNT); for(int i = 2;i < Seg_CNT;++i){ if(AR[i] != AR[i - 1]){ AR[HASH_SEG_CNT] = AR[i]; POS[AR[i]] = HASH_SEG_CNT++; } } for(int i = 1;i < HASH_SEG_CNT;++i){ AR[i] = AR[i + 1] - AR[i]; } }
1~MOD的逆元 √
#define mod 9973ll typedef long long LL; LL inv[mod]; inv[1] = 1; for(int i = 2;i < mod;++i) inv[i] = (mod - mod / i) * (inv[mod % i]) % mod;
相关文章推荐
- oi各种模板总结
- 数论学习总结 | 各种模板
- [置顶] 【计算几何各种小模板总结贴】[不定期更新]
- .vm模板文件各种判断为null或者“null”或者“”总结
- 各种进程创建方式比较总结(MacOS, Win32, Qt)
- ACM题集以及各种总结大全
- 论坛各种问题总结--(随时更新)
- 实践总结ajax各种使用方式(下)
- opencv各种内存泄露情况的大总结
- 数据结构回顾和总结(树的各种遍历方法)(2)
- 天津大学各种Latex模板共享链接
- 各种排序算法的总结和比较
- 总结:Ruby中的@ % # $等各种千奇百怪的符号的含义等
- 面试总结之Java各种修饰符总结
- C 语言资源大全总结--各种框架各种开源库,c开发必备
- 数论模板总结
- ACM题集以及各种总结大全!
- 算法总结之几何模板
- Laravel各种错误总结,不定期更新
- ACM图算法——最大流各种算法总结