这是一篇又长又烂的学习笔记,请做好及时退出的准备。

KD-Tree 的复杂度大概是 \(O(n^{1-\frac{1}{k}})\)

\(k\) 是维度

由于网上找不到靠谱的证明,咕了。

会证明之后再补上。

前置?

  • 考虑到平衡树不能做多维,kdt就是扩展到多维情况
  • 每次 \(nth\_element\) 的复杂度是 \(O(n)\) 的。
  • 类似替罪羊的想法,如果树不够平衡,直接 pia 重构
  • 考虑你删除元素不方便,据说只能打上标记啥的)
  • 但是你插入元素不改变树的大致结构 qwqwq

建树显然是 \(n \log n\) 的

插入据说是 \(n \log^2 n\) 的

查询依旧是 \(n \log n\) 的 qwq

  • 考虑建树



假设最开始有这么多个点



选一个中位数,把空间一分为二

左边作为左儿子,右边作为右儿子



再取一次

我们定义初始是这样

类似平衡树的结构



建出来的树长成这样子

然后像平衡树一样维护最小横坐标,纵坐标,最大横坐标,纵坐标,当前权值,当前坐标,sum值,就可以了。

代码亦不难

  1. int build(int l , int r , int p) {
  2. now = p ;
  3. int mid = l + r >> 1 ;
  4. nth_element(data + l , data + mid , data + r + 1) ; // data 是原数组 qwq 是 KDT
  5. qwq[mid] = data[mid] ;
  6. if(l < mid) qwq[mid].ls = build(l , mid - 1 , p ^ 1) ;
  7. if(r > mid) qwq[mid].rs = build(mid + 1 , r , p ^ 1) ;
  8. pushup(mid) ; return mid ;
  9. }
  • 考虑修改

插入时要判是否平衡,如果不平衡就擦除一整棵子树并重构。(类似替罪羊树的想法

  1. void Erase(int x) {
  2. if (!x) return;
  3. pp[++m] = P[x], Erase(ls(x)), Erase(rs(x)), erase(x);
  4. }
  5. inline void insert(Point p) {
  6. int top = -1, x = root;
  7. if (!x) {
  8. pp[1] = p, root = build(1, 1, 1);
  9. return;
  10. }
  11. while (233) {
  12. if (max(sz[ls(x)], sz[rs(x)]) > sz[x] * alpha && top == -1) top = x;
  13. ++sz[x], cmin(L[x][0], p.x), cmax(R[x][0], p.x), cmin(L[x][1], p.y), cmax(R[x][1], p.y);
  14. int& y = ch[x][(tp[x] == 0) ? (!cmpx(p, P[x])) : (!cmpy(p, P[x]))];
  15. if (!y) {
  16. y = NewNode();
  17. L[y][0] = R[y][0] = p.x, L[y][1] = R[y][1] = p.y, sz[y] = 1, tp[y] = tp[x] ^ 1, fa[y] = x, P[y] = p;
  18. break;
  19. }
  20. x = y;
  21. }
  22. if (top == -1) return;
  23. m = 0;
  24. if (top == root) {
  25. Erase(top), root = build(1, m, 1);
  26. return;
  27. }
  28. int f = fa[top], &t = ch[f][(tp[f] == 0) ? (!cmpx(P[top], P[f])) : (!cmpy(P[top], P[f]))];
  29. Erase(top), t = build(1, m, tp[f]);
  30. }

这样就可以了

询问其实因题目而定的。。没什么具体做法

  1. int query(int x, int l0, int r0, int l1, int r1) {
  2. if (!x) return 0;
  3. if (l0 <= L[x][0] && R[x][0] <= r0 && l1 <= L[x][1] && R[x][1] <= r1) return sz[x];
  4. if (r0 < L[x][0] || R[x][0] < l0 || r1 < L[x][1] || R[x][1] < l1) return 0;
  5. return query(ls(x), l0, r0, l1, r1) + query(rs(x), l0, r0, l1, r1) +
  6. (l0 <= P[x].x && P[x].x <= r0 && l1 <= P[x].y && P[x].y <= r1);
  7. }

比如这个就是二维数点查询个数的方法

然后考虑一个东西,即维数问题

像 \(cdq\)分治,你可以直接三维 \(kdt\) 直接狂 T 不止

也可以排个序然后卡卡常数过去啥的)

三维偏序

  1. #include <bits/stdc++.h>
  2. #define rep(i, x, y) for (register int i = x; i <= y; i++)
  3. using namespace std;
  4. using ll = long long;
  5. using pii = pair<int, int>;
  6. const static int _ = 1 << 20;
  7. char fin[_], *p1 = fin, *p2 = fin;
  8. inline char gc() { return (p1 == p2) && (p2 = (p1 = fin) + fread(fin, 1, _, stdin), p1 == p2) ? EOF : *p1++; }
  9. inline int read() {
  10. bool sign = 1;
  11. char c = 0;
  12. while (c < 48) ((c = gc()) == 45) && (sign = 0);
  13. int x = (c & 15);
  14. while ((c = gc()) > 47) x = (x << 1) + (x << 3) + (c & 15);
  15. return sign ? x : -x;
  16. }
  17. template <class T>
  18. void print(T x, char c = '\n') {
  19. (x == 0) && (putchar(48)), (x < 0) && (putchar(45), x = -x);
  20. static char _st[100];
  21. int _stp = 0;
  22. while (x) _st[++_stp] = x % 10 ^ 48, x /= 10;
  23. while (_stp) putchar(_st[_stp--]);
  24. putchar(c);
  25. }
  26. template <class T>
  27. void cmax(T& x, T y) {
  28. (x < y) && (x = y);
  29. }
  30. template <class T>
  31. void cmin(T& x, T y) {
  32. (x > y) && (x = y);
  33. }
  34. const double alpha = 0.7;
  35. const int N = 1e5 + 10;
  36. int n, k;
  37. int ch[N][2], fa[N], sz[N], tp[N];
  38. int L[N][2], R[N][2];
  39. int st[N], top = 0;
  40. #define ls(x) ch[x][0]
  41. #define rs(x) ch[x][1]
  42. struct Point {
  43. int x, y, z, id;
  44. bool operator==(const Point& other) const { return x == other.x && y == other.y && z == other.z; }
  45. } p[N], P[N], pp[N];
  46. inline bool cmpx(const Point& x, const Point& y) {
  47. return (x.x == y.x) ? (x.y == y.y ? x.id < y.id : x.y < y.y) : x.x < y.x;
  48. }
  49. inline bool cmpy(const Point& x, const Point& y) {
  50. return (x.y == y.y) ? (x.x == y.x ? x.id < y.id : x.x < y.x) : x.y < y.y;
  51. }
  52. int root = 0, cnt = 0;
  53. inline void erase(int x) {
  54. st[++top] = x, ls(x) = rs(x) = sz[x] = L[x][0] = R[x][0] = L[x][1] = R[x][1] = 0;
  55. P[x] = { 0, 0, 0, 0 };
  56. }
  57. int m;
  58. inline int NewNode() { return top ? st[top--] : ++cnt; }
  59. int build(int l, int r, int lst) {
  60. if (l > r) return 0;
  61. int x = NewNode(), mn = 1e9, mx = -1e9;
  62. rep(i, l, r) cmin(mn, pp[i].x), cmax(mx, pp[i].x);
  63. L[x][0] = mn, R[x][0] = mx;
  64. mn = 1e9, mx = -1e9;
  65. rep(i, l, r) cmin(mn, pp[i].y), cmax(mx, pp[i].y);
  66. L[x][1] = mn, R[x][1] = mx, tp[x] = lst ^ 1;
  67. int mid = l + r >> 1;
  68. (lst) ? nth_element(pp + l, pp + mid, pp + r + 1, cmpx) : nth_element(pp + l, pp + mid, pp + r + 1, cmpy);
  69. P[x] = pp[mid], ls(x) = build(l, mid - 1, lst ^ 1), rs(x) = build(mid + 1, r, lst ^ 1);
  70. if (ls(x)) fa[ls(x)] = x;
  71. if (rs(x)) fa[rs(x)] = x;
  72. sz[x] = sz[ls(x)] + sz[rs(x)] + 1;
  73. return x;
  74. }
  75. void Erase(int x) {
  76. if (!x) return;
  77. pp[++m] = P[x], Erase(ls(x)), Erase(rs(x)), erase(x);
  78. }
  79. inline void insert(Point p) {
  80. int top = -1, x = root;
  81. if (!x) {
  82. pp[1] = p, root = build(1, 1, 1);
  83. return;
  84. }
  85. while (233) {
  86. if (max(sz[ls(x)], sz[rs(x)]) > sz[x] * alpha && top == -1) top = x;
  87. ++sz[x], cmin(L[x][0], p.x), cmax(R[x][0], p.x), cmin(L[x][1], p.y), cmax(R[x][1], p.y);
  88. int& y = ch[x][(tp[x] == 0) ? (!cmpx(p, P[x])) : (!cmpy(p, P[x]))];
  89. if (!y) {
  90. y = NewNode();
  91. L[y][0] = R[y][0] = p.x, L[y][1] = R[y][1] = p.y, sz[y] = 1, tp[y] = tp[x] ^ 1, fa[y] = x, P[y] = p;
  92. break;
  93. }
  94. x = y;
  95. }
  96. if (top == -1) return;
  97. m = 0;
  98. if (top == root) {
  99. Erase(top), root = build(1, m, 1);
  100. return;
  101. }
  102. int f = fa[top], &t = ch[f][(tp[f] == 0) ? (!cmpx(P[top], P[f])) : (!cmpy(P[top], P[f]))];
  103. Erase(top), t = build(1, m, tp[f]);
  104. }
  105. int query(int x, int l0, int r0, int l1, int r1) {
  106. if (!x) return 0;
  107. if (l0 <= L[x][0] && R[x][0] <= r0 && l1 <= L[x][1] && R[x][1] <= r1) return sz[x];
  108. if (r0 < L[x][0] || R[x][0] < l0 || r1 < L[x][1] || R[x][1] < l1) return 0;
  109. return query(ls(x), l0, r0, l1, r1) + query(rs(x), l0, r0, l1, r1) +
  110. (l0 <= P[x].x && P[x].x <= r0 && l1 <= P[x].y && P[x].y <= r1);
  111. }
  112. int ans[N], Cnt[N];
  113. signed main() {
  114. #ifdef _WIN64
  115. freopen("testdata.in", "r", stdin);
  116. #endif
  117. n = read(), k = read();
  118. rep(i, 1, n) { p[i].x = read(), p[i].y = read(), p[i].z = read(), p[i].id = i; }
  119. sort(p + 1, p + n + 1, [](const Point& x, const Point& y) { return x.z == y.z ? cmpx(x, y) : x.z < y.z; });
  120. for (int l = 1, r; l <= n; l = r + 1) {
  121. r = l;
  122. while (r < n && p[r + 1] == p[r]) insert(p[r++]);
  123. ans[r] = query(root, -1e9, p[r].x, -1e9, p[r].y), Cnt[ans[r]] += r - l + 1, insert(p[r]);
  124. }
  125. rep(i, 0, n - 1) print(Cnt[i]);
  126. return 0;
  127. }

天使玩偶/SJY摆棋子

  1. #include <bits/stdc++.h>
  2. #define rep(i , x , y) for(register int i = (x) , _## i = ((y) + 1) ; i < _## i ; i ++)
  3. #define Rep(i , x , y) for(register int i = (x) , _## i = ((y) - 1) ; i > _## i ; i --)
  4. using namespace std ;
  5. //#define int long long
  6. using ll = long long ;
  7. using pii = pair < int , int > ;
  8. const static int _ = 1 << 20 ;
  9. char fin[_] , * p1 = fin , * p2 = fin ;
  10. inline char gc() {
  11. return (p1 == p2) && (p2 = (p1 = fin) + fread(fin , 1 , _ , stdin) , p1 == p2) ? EOF : * p1 ++ ;
  12. }
  13. inline int read() {
  14. bool sign = 1 ;
  15. char c = 0 ;
  16. while(c < 48) ((c = gc()) == 45) && (sign = 0) ;
  17. int x = (c & 15) ;
  18. while((c = gc()) > 47) x = (x << 1) + (x << 3) + (c & 15) ;
  19. return sign ? x : -x ;
  20. }
  21. template < class T > void print(T x , char c = '\n') {
  22. (x == 0) && (putchar(48)) , (x < 0) && (putchar(45) , x = -x) ;
  23. static char _st[100] ;
  24. int _stp = 0 ;
  25. while(x) _st[++ _stp] = x % 10 ^ 48 , x /= 10 ;
  26. while(_stp) putchar(_st[_stp --]) ;
  27. putchar(c) ;
  28. }
  29. template < class T > void cmax(T & x , T y) {
  30. (x < y) && (x = y) ;
  31. }
  32. template < class T > void cmin(T & x , T y) {
  33. (x > y) && (x = y) ;
  34. }
  35. struct KDT {
  36. int x , y ;
  37. };
  38. bool cmp1(const KDT & x , const KDT & y) {
  39. return x.x < y.x ;
  40. }
  41. bool cmp2(const KDT & x , const KDT & y) {
  42. return x.y < y.y ;
  43. }
  44. int n , m , ans ;
  45. const int N = 3e6 + 10 ;
  46. KDT t[N] ;
  47. int ls[N] , rs[N] , p[N][2] , mx[N][2] , mn[N][2] ;
  48. void pushup(int x) {
  49. cmax(mx[x][0] , mx[ls[x]][0]) , cmax(mx[x][0] , mx[rs[x]][0]) ;
  50. cmax(mx[x][1] , mx[ls[x]][1]) , cmax(mx[x][1] , mx[rs[x]][1]) ;
  51. cmin(mn[x][0] , mn[ls[x]][0]) , cmin(mn[x][0] , mn[rs[x]][0]) ;
  52. cmin(mn[x][1] , mn[ls[x]][1]) , cmin(mn[x][1] , mn[rs[x]][1]) ;
  53. }
  54. int mxd = 0 , tot = 0 ;
  55. void ins(int & now , int x , int y , int d , int dep) {
  56. if(! now) {
  57. now = ++ tot ;
  58. p[now][0] = x ;
  59. p[now][1] = y ;
  60. mx[now][0] = mn[now][0] = x ;
  61. mx[now][1] = mn[now][1] = y ;
  62. mxd = dep ;
  63. return ;
  64. }
  65. if(! d && x < p[now][d]) ins(ls[now] , x , y , d ^ 1 , dep + 1) ;
  66. else if(! d) ins(rs[now] , x , y , d ^ 1 , dep + 1) ;
  67. else if(y < p[now][d]) ins(ls[now] , x , y , d ^ 1 , dep + 1) ;
  68. else ins(rs[now] , x , y , d ^ 1 , dep + 1) ;
  69. pushup(now) ;
  70. }
  71. void qry(int & dis , int x , int y , int now) {
  72. dis = 0 ;
  73. if(x > mx[now][0]) dis += x - mx[now][0] ;
  74. if(x < mn[now][0]) dis += mn[now][0] - x ;
  75. if(y > mx[now][1]) dis += y - mx[now][1] ;
  76. if(y < mn[now][1]) dis += mn[now][1] - y ;
  77. }
  78. void query(int now , int x , int y) {
  79. int disn = abs(x - p[now][0]) + abs(y - p[now][1]) ;
  80. cmin(ans , disn) ;
  81. int dl = 0x3f3f3f3f ;
  82. int dr = dl ;
  83. if(ls[now]) qry(dl , x , y , ls[now]) ;
  84. if(rs[now]) qry(dr , x , y , rs[now]) ;
  85. if(dl < dr) {
  86. if(dl < ans) query(ls[now] , x , y) ;
  87. if(dr < ans) query(rs[now] , x , y) ;
  88. } else {
  89. if(dr < ans) query(rs[now] , x , y) ;
  90. if(dl < ans) query(ls[now] , x , y) ;
  91. }
  92. }
  93. int build(int l , int r , int d) {
  94. if(l > r) return 0 ;
  95. int mid = l + r >> 1 ;
  96. nth_element(t + l , t + mid , t + r + 1 , d ? cmp1 : cmp2) ;
  97. int now = ++ tot ;
  98. mx[now][0] = mn[now][0] = p[now][0] = t[mid].x ;
  99. mx[now][1] = mn[now][1] = p[now][1] = t[mid].y ;
  100. ls[now] = build(l , mid - 1 , d ^ 1) ;
  101. rs[now] = build(mid + 1 , r , d ^ 1) ;
  102. pushup(now) ;
  103. return now ;
  104. }
  105. signed main() {
  106. #ifdef _WIN64
  107. freopen("testdata.in" , "r" , stdin) ;
  108. #endif
  109. memset(mn , 0x3f , sizeof(mn)) ;
  110. memset(mx , 0xcf , sizeof(mx)) ;
  111. n = read() ;
  112. m = read() ;
  113. rep(i , 1 , n) {
  114. t[i].x = read() ;
  115. t[i].y = read() ;
  116. }
  117. build(1 , n , 0) ;
  118. int rt = 1 ;
  119. rep(i , 1 , m) {
  120. int opt = read() , x = read() , y = read() ;
  121. if(opt == 1) {
  122. ins(rt , x , y , 0 , 1) ;
  123. t[++ n] = { x , y } ;
  124. if(mxd > sqrt(tot)) tot = 0 , build(1 , n , 0) ;
  125. } else {
  126. ans = 0x3f3f3f3f ;
  127. query(rt , x , y) ;
  128. print(ans) ;
  129. }
  130. }
  131. return 0 ;
  132. }

巧克力王国

  1. // powered by c++11
  2. // by Isaunoya
  3. #include<bits/stdc++.h>
  4. #define rep(i , x , y) for(register int i = (x) ; i < (y) ; i ++)
  5. using namespace std ;
  6. using db = double ;
  7. using ll = long long ;
  8. using uint = unsigned int ;
  9. #define int long long
  10. using pii = pair < int , int > ;
  11. #define ve vector
  12. #define Tp template
  13. #define all(v) v.begin() , v.end()
  14. #define sz(v) ((int)v.size())
  15. #define pb emplace_back
  16. #define fir first
  17. #define sec second
  18. // the cmin && cmax
  19. Tp < class T > void cmax(T & x , const T & y) {
  20. if(x < y) x = y ;
  21. }
  22. Tp < class T > void cmin(T & x , const T & y) {
  23. if(x > y ) x = y ;
  24. }
  25. // sort , unique , reverse
  26. Tp < class T > void sort(ve < T > & v) {
  27. sort(all(v)) ;
  28. }
  29. Tp < class T > void unique(ve < T > & v) {
  30. sort(all(v)) ;
  31. v.erase(unique(all(v)) , v.end()) ;
  32. }
  33. Tp < class T > void reverse(ve < T > & v) {
  34. reverse(all(v)) ;
  35. }
  36. int n , m , now = 0 ;
  37. struct node {
  38. int d[2] , ls , rs , val , sum ;
  39. int mx[2] , mn[2] ;
  40. bool operator < (const node & other) const {
  41. return d[now] < other.d[now] ;
  42. }
  43. } ;
  44. const int maxn = 5e4 + 10 ;
  45. node data[maxn] , qwq[maxn] ;
  46. void pushup(int o) {
  47. int ls = qwq[o].ls , rs = qwq[o].rs ;
  48. for(int i = 0 ; i < 2 ; i ++) {
  49. qwq[o].mx[i] = qwq[o].mn[i] = qwq[o].d[i] ;
  50. if(ls) {
  51. cmin(qwq[o].mn[i] , qwq[ls].mn[i]) ;
  52. cmax(qwq[o].mx[i] , qwq[ls].mx[i]) ;
  53. }
  54. if(rs) {
  55. cmin(qwq[o].mn[i] , qwq[rs].mn[i]) ;
  56. cmax(qwq[o].mx[i] , qwq[rs].mx[i]) ;
  57. }
  58. }
  59. qwq[o].sum = qwq[o].val ;
  60. if(ls) qwq[o].sum += qwq[ls].sum ;
  61. if(rs) qwq[o].sum += qwq[rs].sum ;
  62. }
  63. int build(int l , int r , int p) {
  64. now = p ;
  65. int mid = l + r >> 1 ;
  66. nth_element(data + l , data + mid , data + r + 1) ;
  67. qwq[mid] = data[mid] ;
  68. if(l < mid) qwq[mid].ls = build(l , mid - 1 , p ^ 1) ;
  69. if(r > mid) qwq[mid].rs = build(mid + 1 , r , p ^ 1) ;
  70. pushup(mid) ; return mid ;
  71. }
  72. int a , b , c ;
  73. int chk(int x , int y) { return x * a + y * b < c ; }
  74. int qry(int p) {
  75. int cnt = 0 ;
  76. cnt += chk(qwq[p].mn[0] , qwq[p].mn[1]) ;
  77. cnt += chk(qwq[p].mn[0] , qwq[p].mx[1]) ;
  78. cnt += chk(qwq[p].mx[0] , qwq[p].mn[1]) ;
  79. cnt += chk(qwq[p].mx[0] , qwq[p].mx[1]) ;
  80. if(cnt == 4) return qwq[p].sum ;
  81. if(! cnt) return 0 ;
  82. int res = 0 ;
  83. if(chk(qwq[p].d[0] , qwq[p].d[1])) res += qwq[p].val ;
  84. if(qwq[p].ls) res += qry(qwq[p].ls) ;
  85. if(qwq[p].rs) res += qry(qwq[p].rs) ;
  86. return res ;
  87. }
  88. int rt = 0 ;
  89. signed main() {
  90. ios_base :: sync_with_stdio(false) ;
  91. cin.tie(nullptr) , cout.tie(nullptr) ;
  92. // code begin.
  93. cin >> n >> m ;
  94. for(int i = 1 ; i <= n ; i ++) {
  95. cin >> data[i].d[0] >> data[i].d[1] >> data[i].val ;
  96. }
  97. rt = build(1 , n , 0) ;
  98. for(int i = 1 ; i <= m ; i ++) {
  99. cin >> a >> b >> c ;
  100. cout << qry(rt) << '\n' ;
  101. }
  102. return 0 ;
  103. // code end.
  104. }

KD-Tree 学习笔记的更多相关文章

  1. k-d tree 学习笔记

    以下是一些奇怪的链接有兴趣的可以看看: https://blog.sengxian.com/algorithms/k-dimensional-tree http://zgjkt.blog.uoj.ac ...

  2. K-D Tree学习笔记

    用途 做各种二维三维四维偏序等等. 代替空间巨大的树套树. 数据较弱的时候水分. 思想 我们发现平衡树这种东西功能强大,然而只能做一维上的询问修改,显得美中不足. 于是我们尝试用平衡树的这种二叉树结构 ...

  3. kd tree学习笔记 (最近邻域查询)

    https://zhuanlan.zhihu.com/p/22557068 http://blog.csdn.net/zhjchengfeng5/article/details/7855241 KD树 ...

  4. 珂朵莉树(Chtholly Tree)学习笔记

    珂朵莉树(Chtholly Tree)学习笔记 珂朵莉树原理 其原理在于运用一颗树(set,treap,splay......)其中要求所有元素有序,并且支持基本的操作(删除,添加,查找......) ...

  5. dsu on tree学习笔记

    前言 一次模拟赛的\(T3\):传送门 只会\(O(n^2)\)的我就\(gg\)了,并且对于题解提供的\(\text{dsu on tree}\)的做法一脸懵逼. 看网上的其他大佬写的笔记,我自己画 ...

  6. Link Cut Tree学习笔记

    从这里开始 动态树问题和Link Cut Tree 一些定义 access操作 换根操作 link和cut操作 时间复杂度证明 Link Cut Tree维护链上信息 Link Cut Tree维护子 ...

  7. 矩阵树定理(Matrix Tree)学习笔记

    如果不谈证明,稍微有点线代基础的人都可以在两分钟内学完所有相关内容.. 行列式随便找本线代书看一下基本性质就好了. 学习资源: https://www.cnblogs.com/candy99/p/64 ...

  8. splay tree 学习笔记

    首先感谢litble的精彩讲解,原文博客: litble的小天地 在学完二叉平衡树后,发现这是只是一个不稳定的垃圾玩意,真正实用的应有Treap.AVL.Splay这样的查找树.于是最近刚学了学了点S ...

  9. LSM Tree 学习笔记——本质是将随机的写放在内存里形成有序的小memtable,然后定期合并成大的table flush到磁盘

    The Sorted String Table (SSTable) is one of the most popular outputs for storing, processing, and ex ...

  10. LSM Tree 学习笔记——MemTable通常用 SkipList 来实现

    最近发现很多数据库都使用了 LSM Tree 的存储模型,包括 LevelDB,HBase,Google BigTable,Cassandra,InfluxDB 等.之前还没有留意这么设计的原因,最近 ...

随机推荐

  1. 用上自己的线程池,实现自己的RPC框架

    package github.com.AllenDuke.rpc.customer; import github.com.AllenDuke.rpc.netty.NettyClient; import ...

  2. 7天用Go动手写/从零实现Web框架Gee

    设计一个框架 大部分时候,我们需要实现一个 Web 应用,第一反应是应该使用哪个框架.不同的框架设计理念和提供的功能有很大的差别.比如 Python 语言的 django和flask,前者大而全,后者 ...

  3. 浅谈C语言的数据存储(一)

    作者:冯老师,华清远见嵌入式学院讲师. 程序由指令和数据组成,C语言程序亦是如此.开发者在编写程序的时候往往需要根据不同数据的特点以及程序需求来选择不同的数据存储方式,那么在C语言中数据的存储分为哪些 ...

  4. nginx 源码编译 用OPENSSL源码 开启 SSL

    ./configure --prefix=/usr/local/nginx --with-openssl=/home/uniqs/thirdparty/openssl/openssl-1.1.1d - ...

  5. JAVA环境配置(Windows10)

    Java开发环境配置 下载JDK 首先我们需要下载java开发工具包JDK,下载地址:https://www.oracle.com/technetwork/java/javase/downloads/ ...

  6. 【原创】(二)Linux进程调度器-CPU负载

    背景 Read the fucking source code! --By 鲁迅 A picture is worth a thousand words. --By 高尔基 说明: Kernel版本: ...

  7. Django 搭建

    1.安装python 2.pip 安装 Django  2.1.3 是版本号 命令:pip install Django==2.1.3 3.数据库驱动: mysql 数据库配置文档: 下载 whl 文 ...

  8. Linux tcpdump 命令详解与示例

    命令概要 Linux作为网络服务器,特别是作为路由器和网关时,数据的采集和分析是不可少的.TcpDump 是 Linux 中强大的网络数据采集分析工具之一. 用简单的话来定义tcpdump,就是:du ...

  9. 06-Spring03-事务管理

    今日知识 1. Spring事务管理 2. 转账案例 Spring事务管理 1. 事务特性(ACID) 1. 原子性:整体 [原子性是指事务包含的所有操作要么全部成功,要么全部失败] 2. 一致性:数 ...

  10. 连接数据库方法---DAO,RDO,OLE,ADO

    2012-12-14 09:40 (分类:计算机程序) DAO (Data Access Objects) 提供了一种通过程序代码创建和操纵数据库的机制.最大特点是对MICROSOFT JET(Jet ...