求LCA练习+部分算法复习 2017.1.22
第一题就LCA即可。不过推荐用Tarjan(最快,常数很小)。然后Tarjan的时候顺便就出一个dist[i],表示i节点到根节点的距离。求出了LCA,那么两点间的距离就为dist[u] + dist[v] - 2 * dist[lca]。
Code
#include<iostream>
#include<sstream>
#include<cstdio>
#include<cmath>
#include<cstdlib>
#include<cstring>
#include<cctype>
#include<queue>
#include<set>
#include<map>
#include<stack>
#include<vector>
#include<algorithm>
#ifndef WIN32
#define AUTO "%I64d"
#else
#define AUTO "%lld"
#endif
using namespace std;
typedef bool boolean;
#define smin(a, b) (a) = min((a), (b))
#define smax(a, b) (a) = max((a), (b))
template<typename T>
inline void readInteger(T& u){
char x;
int aFlag = ;
while(!isdigit((x = getchar())) && x != '-');
if(x == '-'){
aFlag = -;
x = getchar();
}
for(u = x - ''; isdigit((x = getchar())); u = u * + x - '');
ungetc(x, stdin);
u *= aFlag;
} typedef class Edge {
public:
int end;
int next;
int w;
Edge(const int end = , const int next = , const int w = ):end(end), next(next), w(w){ }
}Edge; typedef class MapManager{
public:
int ce;
Edge* edges;
int* h;
MapManager():ce(), edges(NULL), h(NULL){ }
MapManager(int points, int limit):ce(){
edges = new Edge[(const int)(limit + )];
h = new int[(const int)(points + )];
memset(h, , sizeof(int) * (points + ));
}
inline void addEdge(int from, int end, int w){
edges[++ce] = Edge(end, h[from], w);
h[from] = ce;
}
inline void addDoubleEdge(int from, int end, int w){
addEdge(from, end, w);
addEdge(end, from, w);
}
Edge& operator [](int pos){
return edges[pos];
}
}MapManager;
#define m_begin(g, i) (g).h[(i)] typedef class union_found{
public:
int *f;
union_found():f(NULL) {}
union_found(int points) {
f = new int[(const int)(points + )];
}
int find(int x) {
if(f[x] != x) return f[x] = find(f[x]);
return f[x];
}
void unit(int fa, int so) {
int ffa = find(fa);
int fso = find(so);
f[fso] = ffa;
}
int& operator [](int pos){
return f[pos];
}
}union_found; int n, m;
MapManager g;
MapManager q;
int *results;
boolean* enable;
int *querya, *queryb;
union_found uf;
boolean* visited;
int* dist; inline void init(){
readInteger(n);
g = MapManager(n, * n);
for(int i = , a, b, c; i < n; i++){
readInteger(a);
readInteger(b);
readInteger(c);
g.addDoubleEdge(a, b, c);
}
readInteger(m);
q = MapManager(n, * m);
querya = new int[(const int)(m + )];
queryb = new int[(const int)(m + )];
results = new int[(const int)(m + )];
enable = new boolean[(const int)(m + )];
dist = new int[(const int)(n + )];
uf = union_found(n);
visited = new boolean[(const int)(n + )];
memset(visited, false, sizeof(boolean) * (n + ));
memset(enable, true, sizeof(boolean) * (m + ));
for(int i = ; i <= m; i++){
readInteger(querya[i]);
readInteger(queryb[i]);
q.addDoubleEdge(querya[i], queryb[i], i);
}
dist[] = ;
} void tarjan(int node, int f){
uf[node] = node;
visited[node] = true;
for(int i = m_begin(g, node); i != ; i = g[i].next){
int& e = g[i].end;
if(e == f) continue;
dist[e] = dist[node] + g[i].w;
tarjan(e, node);
uf[e] = node;
}
for(int i = m_begin(q, node); i != ; i = q[i].next) {
int& e = q[i].end;
if(visited[e] && enable[q[i].w]){
int lca = uf.find(e);
results[q[i].w] = lca;
enable[q[i].w] = false;
}
}
} inline void solve(){
tarjan(, );
for(int i = ; i <= m; i++){
int dis = dist[querya[i]] + dist[queryb[i]] - * dist[results[i]];
printf("%d\n", dis);
}
} int main(){
freopen("distance.in", "r", stdin);
freopen("distance.out", "w", stdout);
init();
solve();
return ;
}
distance (Tarjan)
#include<iostream>
#include<sstream>
#include<cstdio>
#include<cmath>
#include<cstdlib>
#include<cstring>
#include<cctype>
#include<queue>
#include<set>
#include<map>
#include<stack>
#include<vector>
#include<algorithm>
#ifndef WIN32
#define AUTO "%I64d"
#else
#define AUTO "%lld"
#endif
using namespace std;
typedef bool boolean;
#define smin(a, b) (a) = min((a), (b))
#define smax(a, b) (a) = max((a), (b))
template<typename T>
inline void readInteger(T& u){
char x;
int aFlag = ;
while(!isdigit((x = getchar())) && x != '-');
if(x == '-'){
aFlag = -;
x = getchar();
}
for(u = x - ''; isdigit((x = getchar())); u = u * + x - '');
ungetc(x, stdin);
u *= aFlag;
} template<typename T>class Matrix{
public:
T *p;
int lines;
int rows;
Matrix():p(NULL){ }
Matrix(int rows, int lines):lines(lines), rows(rows){
p = new T[(lines * rows)];
}
T* operator [](int pos){
return (p + pos * lines);
}
};
#define matset(m, i, s) memset((m).p, (i), (s) * (m).lines * (m).rows) ///map template starts
typedef class Edge{
public:
int end;
int next;
int w;
Edge(const int end = , const int next = , const int w = ):end(end), next(next), w(w){}
}Edge;
typedef class MapManager{
public:
int ce;
int *h;
int w;
Edge *edge;
MapManager(){}
MapManager(int points, int limit):ce(){
h = new int[(const int)(points + )];
edge = new Edge[(const int)(limit + )];
memset(h, , sizeof(int) * (points + ));
}
inline void addEdge(int from, int end, int w){
edge[++ce] = Edge(end, h[from], w);
h[from] = ce;
}
inline void addDoubleEdge(int from, int end, int w){
addEdge(from, end, w);
addEdge(end, from, w);
}
Edge& operator[] (int pos) {
return edge[pos];
}
}MapManager;
#define m_begin(g, i) (g).h[(i)]
///map template ends int n, m;
int cnt = ;
Matrix<int> st;
int* seq;
int* dep;
int *app;
MapManager g;
int *mlog2;
long long *dist; inline void init() {
readInteger(n);
g = MapManager(n, * n);
seq = new int[(const int)( * n + )];
dist = new long long[(const int)(n + )];
dep = new int[(const int)(n + )];
app = new int[(const int)(n + )];
for(int i = , a, b, w; i < n; i++){
readInteger(a);
readInteger(b);
readInteger(w);
g.addDoubleEdge(a, b, w);
}
dist[] = ;
dep[] = ;
} void dfs(int node, int f) {
seq[++cnt] = node;
app[node] = cnt;
dep[node] = dep[f] + ;
for(int i = m_begin(g, node); i != ; i = g[i].next) {
int& e = g[i].end;
if(e == f) continue;
dist[e] = dist[node] + g[i].w;
dfs(e, node);
seq[++cnt] = node;
}
} inline void init_log() {
mlog2 = new int[(const int)( * n + )];
mlog2[] = ;
for(int i = ; i <= * n; i++)
mlog2[i] = mlog2[i / ] + ;
} inline void init_st() {
init_log();
st = Matrix<int>(cnt, mlog2[cnt] + );
for(int i = ; i <= cnt; i++)
st[i][] = seq[i];
for(int j = ; j <= mlog2[cnt]; j++)
for(int i = ; i + ( << j) - <= cnt; i++)
st[i][j] = (dep[st[i][j - ]] < dep[st[i + ( << (j - ))][j - ]]) ? (st[i][j - ]) : (st[i + ( << (j - ))][j - ]);
} inline int lca(int a, int b) {
if(app[a] > app[b]) swap(a, b);
int pos = mlog2[app[b] - app[a] + ];
int u = st[app[a]][pos];
int v = st[app[b] - ( << pos) + ][pos];
return (dep[u] > dep[v]) ? (v) : (u);
} long long dis;
inline void solve() {
readInteger(m);
for(int i = , a, b; i <= m; i++){
readInteger(a);
readInteger(b);
int l = lca(a, b);
dis = dist[a] + dist[b] - * dist[l];
printf(AUTO"\n", dis);
}
} int main() {
freopen("distance.in", "r", stdin);
freopen("distance.out", "w", stdout);
init();
dfs(, );
init_st();
solve();
return ;
}
distance (st table)
话说ST表在n,q都尽量大的情况下,其他数据随机,竟然平均一个点比Tarjan 0.05s左右。(也有可能是我的st表写得比较丑)
第二题还是一遍dfs序,接着可以开开心心地放线段树去装逼了。(然而我把某些"+="写成了"=",于是AK又没有了。。一定是写这道题和检查的时候头脑都不清醒)
Code
#include<iostream>
#include<sstream>
#include<cstdio>
#include<cmath>
#include<cstdlib>
#include<cstring>
#include<cctype>
#include<queue>
#include<set>
#include<map>
#include<stack>
#include<vector>
#include<algorithm>
#ifdef WIN32
#define AUTO "%I64d"
#else
#define AUTO "%lld"
#endif
using namespace std;
typedef bool boolean;
#define smin(a, b) (a) = min((a), (b))
#define smax(a, b) (a) = max((a), (b))
template<typename T>
inline void readInteger(T& u){
char x;
int aFlag = ;
while(!isdigit((x = getchar())) && x != '-');
if(x == '-'){
aFlag = -;
x = getchar();
}
for(u = x - ''; isdigit((x = getchar())); u = u * + x - '');
ungetc(x, stdin);
u *= aFlag;
} typedef class Edge {
public:
int end;
int next;
Edge(const int end = , const int next = ):end(end), next(next){ }
}Edge; typedef class MapManager{
public:
int ce;
Edge* edges;
int* h;
MapManager():ce(), edges(NULL), h(NULL){ }
MapManager(int points, int limit):ce(){
edges = new Edge[(const int)(limit + )];
h = new int[(const int)(points + )];
memset(h, , sizeof(int) * (points + ));
}
inline void addEdge(int from, int end){
edges[++ce] = Edge(end, h[from]);
h[from] = ce;
}
inline void addDoubleEdge(int from, int end){
addEdge(from, end);
addEdge(end, from);
}
Edge& operator [](int pos){
return edges[pos];
}
}MapManager;
#define m_begin(g, i) (g).h[(i)] typedef class SegTreeNode{
public:
long long sum;
int l, r;
SegTreeNode *left, *right;
long long lazy;
SegTreeNode(int l, int r):l(l), r(r), sum(), lazy(), left(NULL), right(NULL){ } inline void pushUp(){
this->sum = left->sum + right->sum;
} inline void pushDown(){
left->lazy += lazy;
right->lazy += lazy;
left->sum += lazy * (left->r - left->l + );
right->sum += lazy * (right->r - right->l + );
lazy = ;
}
}SegTreeNode; typedef class SegTree {
public:
SegTreeNode* root;
SegTree():root(NULL){ }
SegTree(int size) {
build(root, , size);
} void build(SegTreeNode*& node, int l, int r){
node = new SegTreeNode(l, r);
if(l == r) return;
int mid = (l + r) >> ;
build(node->left, l, mid);
build(node->right, mid + , r);
} void update(SegTreeNode*& node, int l, int r, int from, int end, long long val){
if(l == from && r == end){
node->sum += val * (r - l + );
node->lazy += val;
return;
}
if(node->lazy) node->pushDown();
int mid = (l + r) >> ;
if(end <= mid) update(node->left, l, mid, from, end, val);
else if(from > mid) update(node->right, mid + , r, from, end, val);
else{
update(node->left, l, mid, from, mid, val);
update(node->right, mid + , r, mid + , end, val);
}
node->pushUp();
} long long query(SegTreeNode*& node, int index){
if(node->l == index && node->r == index){
return node->sum;
}
if(node->lazy) node->pushDown();
int mid = (node->l + node->r) >> ;
if(index <= mid) return query(node->left, index);
return query(node->right, index);
} long long query(SegTreeNode*& node, int from, int end){
if(node->l == from && node->r == end){
return node->sum;
}
if(node->lazy) node->pushDown();
int mid = (node->l + node->r) >> ;
if(end <= mid) return query(node->left, from, end);
if(from > mid) return query(node->right, from, end);
return query(node->left, from, mid) + query(node->right, mid + , end);
}
}SegTree; int n, m;
SegTree st;
int cnt = ;
int* visitID;
int* exitID;
MapManager g; inline void init() {
readInteger(n);
g = MapManager(n, * n);
for(int i = , a, b; i < n; i++){
readInteger(a);
readInteger(b);
g.addDoubleEdge(a, b);
}
visitID = new int[(const int)(n + )];
exitID = new int[(const int)(n + )];
} void dfs(int node, int last){
visitID[node] = ++cnt;
for(int i = m_begin(g, node); i != ; i = g[i].next) {
int& e = g[i].end;
if(e == last) continue;
dfs(e, node);
}
exitID[node] = cnt;
} inline void solve() {
dfs(, );
readInteger(m);
st = SegTree(n);
char cmd[];
int a, b;
while(m--) {
scanf("%s", cmd);
readInteger(a);
if(cmd[] == 'g') {
readInteger(b);
st.update(st.root, , n, visitID[a], exitID[a], b);
}else if(cmd[] == 's'){
long long res = st.query(st.root, visitID[a]);
printf(AUTO"\n", res);
}else if(cmd[] == 'a'){
long long res = st.query(st.root, visitID[a], exitID[a]);
printf(AUTO"\n", res);
}
}
} int main() {
freopen("redpacket.in", "r", stdin);
freopen("redpacket.out", "w", stdout);
init();
solve();
return ;
}
一看就发现是专为值域线段树设置的裸题。
Code
#include<iostream>
#include<sstream>
#include<cstdio>
#include<cmath>
#include<cstdlib>
#include<cstring>
#include<cctype>
#include<queue>
#include<set>
#include<map>
#include<stack>
#include<vector>
#include<algorithm>
#ifndef WIN32
#define AUTO "%I64d"
#else
#define AUTO "%lld"
#endif
using namespace std;
typedef bool boolean;
#define smin(a, b) (a) = min((a), (b))
#define smax(a, b) (a) = max((a), (b))
template<typename T>
inline void readInteger(T& u){
char x;
int aFlag = ;
while(!isdigit((x = getchar())) && x != '-');
if(x == '-'){
aFlag = -;
x = getchar();
}
for(u = x - ''; isdigit((x = getchar())); u = u * + x - '');
ungetc(x, stdin);
u *= aFlag;
} typedef class SegTreeNode {
public:
int s;
SegTreeNode* left, *right; inline void pushUp(){
s = left->s + right->s;
}
}SegTreeNode; typedef class SegTree {
public:
int lb, rb;
SegTreeNode* root;
SegTree():root(NULL) { }
SegTree(int lb, int rb, int* list):lb(lb), rb(rb){
build(root, , rb - lb + , list);
} void build(SegTreeNode*& node, int l, int r, int* list){
node = new SegTreeNode();
if(l == r){
node->s = list[l];
return;
}
int mid = (l + r) >> ;
build(node->left, l, mid, list);
build(node->right, mid + , r, list);
node->pushUp();
} void update(SegTreeNode*& node, int l, int r, int index, int val){
if(l == index && r == index){
node->s += val;
smax(node->s, );
return;
}
int mid = (l + r) >> ;
if(index <= mid) update(node->left, l, mid, index, val);
else update(node->right, mid + , r, index, val);
node->pushUp();
} int findKth(SegTreeNode*& node, int l, int r, int k){
if(l == r) return l + lb - ;
int ls = node->left->s;
int mid = (l + r) >> ;
if(k <= ls) return findKth(node->left, l, mid, k);
return findKth(node->right, mid + , r, k - ls);
}
}SegTree; int n;
int lb, rb;
int* list;
SegTree st;
inline void init() {
readInteger(lb);
readInteger(rb);
list = new int[(const int)(rb - lb + )];
for(int i = lb; i <= rb; i++){
readInteger(list[i - lb + ]);
}
st = SegTree(lb, rb, list);
} inline void solve() {
const int L = rb - lb + ;
readInteger(n);
char cmd[];
int a;
while(n--) {
scanf("%s", cmd);
readInteger(a);
if(cmd[] == 'a'){
st.update(st.root, , L, a - lb + , );
}else if(cmd[] == 'd'){
st.update(st.root, , L, a - lb + , -);
}else{
int res = st.findKth(st.root, , L, a);
printf("%d\n", res);
}
}
} int main(){
freopen("kth.in", "r", stdin);
freopen("kth.out", "w", stdout);
init();
solve();
return ;
}
值域线段树
然后我还用了替罪羊树(然而发现,都快成普通的二叉搜索树了),O(n)离线建完整棵树,插入删除都不需要重构,即使为count为0也不管(删掉它需要花费更过的时间)。不过测了后发现,略微比值域线段树快一点,应该是因为各种操作在中途完成就开始返回了。
Code
#include<iostream>
#include<sstream>
#include<cstdio>
#include<cmath>
#include<cstdlib>
#include<cstring>
#include<cctype>
#include<queue>
#include<set>
#include<map>
#include<stack>
#include<vector>
#include<algorithm>
#ifndef WIN32
#define AUTO "%I64d"
#else
#define AUTO "%lld"
#endif
using namespace std;
typedef bool boolean;
#define smin(a, b) (a) = min((a), (b))
#define smax(a, b) (a) = max((a), (b))
template<typename T>
inline void readInteger(T& u){
char x;
int aFlag = ;
while(!isdigit((x = getchar())) && x != '-');
if(x == '-'){
aFlag = -;
x = getchar();
}
for(u = x - ''; isdigit((x = getchar())); u = u * + x - '');
ungetc(x, stdin);
u *= aFlag;
} template<typename T>
class ScapegoatTreeNode {
public:
T val;
int count;
int size;
ScapegoatTreeNode* next[];
ScapegoatTreeNode():count(), size(){
memset(next, , sizeof(next));
}
ScapegoatTreeNode(T val):val(val), count(), size(){
memset(next, , sizeof(next));
} inline void maintain() {
size = count;
for(int i = ; i < ; i++)
if(next[i] != NULL)
size += next[i]->size;
} inline void addCount(int c){
if(count == && c < ) return;
size += c, count += c;
} inline int cmp(T x){
if(val == x) return -;
return (x < val) ? () : ();
}
}; template<typename T>
class ScapegoatTree {
protected:
static void insert(ScapegoatTreeNode<T>*& node, T val){
if(node == NULL){
node = new ScapegoatTreeNode<T>(val);
return;
}
int d = node->cmp(val);
if(d == -){
node->addCount();
return;
}
insert(node->next[d], val);
node->maintain();
} static boolean remove(ScapegoatTreeNode<T>*& node, T val){
if(node == NULL) return false;
int d = node->cmp(val);
if(d == -){
node->addCount(-);
return true;
}
boolean res = remove(node->next[d], val);
if(res) node->maintain();
return res;
} static ScapegoatTreeNode<T>* findKth(ScapegoatTreeNode<T>*& node, int k){
int ls = (node->next[] == NULL) ? () : (node->next[]->size);
if(k >= ls + && k <= ls + node->count) return node;
if(k <= ls) return findKth(node->next[], k);
return findKth(node->next[], k - ls - node->count);
}
public:
ScapegoatTreeNode<T>* root;
vector<ScapegoatTreeNode<T>*> lis; ScapegoatTree():root(NULL){ } ScapegoatTreeNode<T>* rebuild(int l, int r){
if(l > r) return NULL;
int mid = (l + r) >> ;
ScapegoatTreeNode<T>*& node = lis[mid];
node->next[] = rebuild(l, mid - );
node->next[] = rebuild(mid + , r);
node->maintain();
return node;
} void rebuild(ScapegoatTreeNode<T>*& node, ScapegoatTreeNode<T>*& f){
lis.clear();
travel(node);
int d = -;
if(f != NULL) d = f->cmp(node->val);
ScapegoatTreeNode<T>* res = rebuild(, lis.size() - );
if(d != -) f->next[d] = res;
else root = res;
} void insert(T val){
insert(root, val);
} void remove(T val){
remove(root, val);
} ScapegoatTreeNode<T>* findKth(int k){
return findKth(root, k);
}
}; int n;
int lb, rb;
ScapegoatTree<int> s; inline void init() {
readInteger(lb);
readInteger(rb);
for(int i = lb; i <= rb; i++){
ScapegoatTreeNode<int>* node = new ScapegoatTreeNode<int>(i);
readInteger(node->count);
node->maintain();
s.lis.push_back(node);
}
s.root = s.rebuild(, s.lis.size() - );
} inline void solve() {
readInteger(n);
char cmd[];
int a;
while(n--) {
scanf("%s", cmd);
readInteger(a);
if(cmd[] == 'a'){
s.insert(a);
}else if(cmd[] == 'd'){
s.remove(a);
}else{
ScapegoatTreeNode<int>* node = s.findKth(a);
printf("%d\n", node->val);
}
}
} int main(){
freopen("kth.in", "r", stdin);
freopen("kth.out", "w", stdout);
init();
solve();
return ;
}
替罪羊树
求LCA练习+部分算法复习 2017.1.22的更多相关文章
- [算法]树上倍增求LCA
LCA指的是最近公共祖先(Least Common Ancestors),如下图所示: 4和5的LCA就是2 那怎么求呢?最粗暴的方法就是先dfs一次,处理出每个点的深度 然后把深度更深的那一个点(4 ...
- 求LCA最近公共祖先的在线倍增算法模板_C++
倍增求 LCA 是在线的,而且比 ST 好写多了,理解起来比 ST 和 Tarjan 都容易,于是就自行脑补吧,代码写得容易看懂 关键理解 f[i][j] 表示 i 号节点的第 2j 个父亲,也就是往 ...
- tarjan算法求LCA
tarjan算法求LCA LCA(Least Common Ancestors)的意思是最近公共祖先,即在一棵树中,找出两节点最近的公共祖先. 这里我们使用tarjan算法离线算法解决这个问题. 离线 ...
- 求LCA最近公共祖先的离线Tarjan算法_C++
这个Tarjan算法是求LCA的算法,不是那个强连通图的 它是 离线 算法,时间复杂度是 O(m+n),m 是询问数,n 是节点数 它的优点是比在线算法好写很多 不过有些题目是强制在线的,此类离线算法 ...
- Tarjan 算法求 LCA / Tarjan 算法求强连通分量
[时光蒸汽喵带你做专题]最近公共祖先 LCA (Lowest Common Ancestors)_哔哩哔哩 (゜-゜)つロ 干杯~-bilibili tarjan LCA - YouTube Tarj ...
- ST(RMQ)算法(在线)求LCA
在此之前,我写过另一篇博客,是倍增(在线)求LCA.有兴趣的同学可以去看一看.概念以及各种暴力就不在这里说了,那篇博客已经有介绍了. 不会ST算法的同学点这里 ST(RMQ)算法在线求LCA 这个算法 ...
- Tarjan算法离线 求 LCA(最近公共祖先)
本文是网络资料整理或部分转载或部分原创,参考文章如下: https://www.cnblogs.com/JVxie/p/4854719.html http://blog.csdn.net/ywcpig ...
- SPOJ COT2 Count on a tree II (树上莫队,倍增算法求LCA)
题意:给一个树图,每个点的点权(比如颜色编号),m个询问,每个询问是一个区间[a,b],图中两点之间唯一路径上有多少个不同点权(即多少种颜色).n<40000,m<100000. 思路:无 ...
- 求最近公共祖先(LCA)的各种算法
水一发题解. 我只是想存一下树剖LCA的代码...... 以洛谷上的这个模板为例:P3379 [模板]最近公共祖先(LCA) 1.朴素LCA 就像做模拟题一样,先dfs找到基本信息:每个节点的父亲.深 ...
随机推荐
- HDU - 5961 传递 想法,bfs
题意:给你一个有向图,满足去掉方向是完全图,将其拆成PQ两个图(没有公共边),问你两图是否分别满足对于任意3个点a,b,c 若有一条边从a到b且有一条边从b到c ,则同样有一条边从a到c. 题解:观察 ...
- IDA的头像
Ada Lovelace,世界第一位女programmer,为Charles Babbage 做了不少工作,IDA 用她的头像作为图标是为了纪念这位女程序员.Wikipedia上有一幅她的很漂亮的画像 ...
- 2018/03/18 isset、empty、is_null的区别
在平常的工作中,判断一个值是否为空的情况时,会直接使用 if ($var) 这种形式,有时也会使用这三个函数进行比较,但是当时也没有很深入的学习. -- 还是通过实例来判断这几个的用法和场景 首先定义 ...
- C++三大特性之多态
原文地址:https://qunxinghu.github.io/2016/09/08/C++%20%E4%B8%89%E5%A4%A7%E7%89%B9%E6%80%A7%E4%B9%8B%E5%A ...
- oracle(二)V$lock 视图中ID1 , ID2 列的含义
1.在Table Locks(TM)中 ID1为对象的id, ID2为0 在Row Locks(TX)中 ID1为Undo Segmen Number与该事务在该回滚段的事务表(Transaction ...
- Spark中cache和persist的区别
cache和persist都是用于将一个RDD进行缓存的,这样在之后使用的过程中就不需要重新计算了,可以大大节省程序运行时间. cache和persist的区别 基于Spark 1.6.1 的源码,可 ...
- POJ1258:Agri-Net(最小生成树模板题)
http://poj.org/problem?id=1258 Description Farmer John has been elected mayor of his town! One of hi ...
- Oil Deposits(poj 1526 DFS入门题)
http://poj.org/problem?id=1562 ...
- SQL Expression Language Tutorial 学习笔记一
http://docs.sqlalchemy.org/en/latest/core/tutorial.html Google 翻译了一下 SQLAlchemy Expression Language, ...
- python中 staticmethod与classmethod
原文地址https://blog.csdn.net/youngbit007/article/details/68957848 原文地址https://blog.csdn.net/weixin_3565 ...