题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=2586

题目:

How far away ?

Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)
Total Submission(s): 21500    Accepted Submission(s): 8471

Problem Description
There are n houses in the village and some bidirectional roads connecting them. Every day peole always like to ask like this "How far is it if I want to go from house A to house B"? Usually it hard to answer. But luckily int this village the answer is always unique, since the roads are built in the way that there is a unique simple path("simple" means you can't visit a place twice) between every two houses. Yout task is to answer all these curious people.
 
Input
First line is a single integer T(T<=10), indicating the number of test cases.
  For each test case,in the first line there are two numbers n(2<=n<=40000) and m (1<=m<=200),the number of houses and the number of queries. The following n-1 lines each consisting three numbers i,j,k, separated bu a single space, meaning that there is a road connecting house i and house j,with length k(0<k<=40000).The houses are labeled from 1 to n.
  Next m lines each has distinct integers i and j, you areato answer the distance between house i and house j.
 
Output
For each test case,output m lines. Each line represents the answer of the query. Output a bland line after each test case.
 
Sample Input
2
3 2
1 2 10
3 1 15
1 2
2 3
 
2 2
1 2 100
1 2
2 1
 
Sample Output
10
25
100
100
 
思路:裸题,套模板即可。
代码实现如下:
 #include <cstdio>
#include <vector>
using namespace std; const int maxn = 4e4 + ;
int n, m, u, v, k;
int fa[maxn][], deep[maxn], cost[maxn]; struct edge {
int v, l;
edge(int v = , int l = ) : v(v), l(l) {}
}; vector<edge> G[maxn]; void dfs(int u, int d, int p) {
deep[u] = d;
fa[u][] = p;
for(int i = ; i < G[u].size(); i++) {
int v = G[u][i].v;
if(v != p) {
cost[v] = cost[u] + G[u][i].l;
dfs(v, d + , u);
}
}
} void lca() {
for(int i = ; i <= n; i++) {
for(int j = ; ( << j) <= n; j++) {
fa[i][j] = -;
}
}
for(int j = ; ( << j) <= n; j++) {
for(int i = ; i <= n; i++) {
if(fa[i][j-] != -) {
fa[i][j] = fa[fa[i][j-]][j-];
}
}
}
} int query(int u, int v) {
if(deep[u] < deep[v]) swap(u, v);
int k;
for(k = ; ( << (k + )) <= deep[u]; k++);
for(int i = k; i >= ; i--) {
if(deep[u] - ( << i) >= deep[v]) {
u = fa[u][i];
}
}
if(u == v) return u;
for(int i = k; i >= ; i--) {
if(fa[u][i] != - && fa[u][i] != fa[v][i]) {
u = fa[u][i];
v = fa[v][i];
}
}
return fa[u][];
} int main() {
int t;
scanf("%d", &t);
while(t--) {
scanf("%d%d", &n, &m);
for(int i = ; i <= n; i++) {
G[i].clear();
}
for(int i = ; i < n; i++) {
scanf("%d%d%d", &u, &v, &k);
G[u].push_back(edge(v, k));
G[v].push_back(edge(u, k));
}
dfs(, , -);
lca();
while(m--) {
scanf("%d%d", &u, &v);
printf("%d\n", cost[u] + cost[v] - * cost[query(u, v)]);
}
}
return ;
}

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=2874

题目:

Connections between cities

Time Limit: 10000/5000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)
Total Submission(s): 13879    Accepted Submission(s): 3159

Problem Description
After World War X, a lot of cities have been seriously damaged, and we need to rebuild those cities. However, some materials needed can only be produced in certain places. So we need to transport these materials from city to city. For most of roads had been totally destroyed during the war, there might be no path between two cities, no circle exists as well.
Now, your task comes. After giving you the condition of the roads, we want to know if there exists a path between any two cities. If the answer is yes, output the shortest path between them.
 
Input
Input consists of multiple problem instances.For each instance, first line contains three integers n, m and c, 2<=n<=10000, 0<=m<10000, 1<=c<=1000000. n represents the number of cities numbered from 1 to n. Following m lines, each line has three integers i, j and k, represent a road between city i and city j, with length k. Last c lines, two integers i, j each line, indicates a query of city i and city j.
 
Output
For each problem instance, one line for each query. If no path between two cities, output “Not connected”, otherwise output the length of the shortest path between them.
 
Sample Input
5 3 2
1 3 2
2 4 3
5 2 3
1 4
4 5
 
Sample Output
Not connected
 
 
题目:
Distance Queries
Time Limit: 2000MS   Memory Limit: 30000K
Total Submissions: 15827   Accepted: 5576
Case Time Limit: 1000MS

Description

Farmer John's cows refused to run in his marathon since he chose a path much too long for their leisurely lifestyle. He therefore wants to find a path of a more reasonable length. The input to this problem consists of the same input as in "Navigation Nightmare",followed by a line containing a single integer K, followed by K "distance queries". Each distance query is a line of input containing two integers, giving the numbers of two farms between which FJ is interested in computing distance (measured in the length of the roads along the path between the two farms). Please answer FJ's distance queries as quickly as possible!

Input

* Lines 1..1+M: Same format as "Navigation Nightmare"

* Line 2+M: A single integer, K. 1 <= K <= 10,000

* Lines 3+M..2+M+K: Each line corresponds to a distance query and contains the indices of two farms.

Output

* Lines 1..K: For each distance query, output on a single line an integer giving the appropriate distance.

Sample Input

7 6
1 6 13 E
6 3 9 E
3 5 7 S
4 1 3 N
2 4 20 W
4 7 2 S
3
1 6
1 4
2 6

Sample Output

13
3
36

Hint

Farms 2 and 6 are 20+3+13=36 apart.
 
思路:不要管这傻逼题面,输入就是裸的LCA输入格式,那个字母也不用管,可以使用%*s来读入字母。
代码实现如下:
 #include <cstdio>
#include <vector>
#include <cstring>
using namespace std; const int maxn = 1e5 + ;
int n, m, q, u, v, k;
int fa[maxn][], deep[maxn], cost[maxn]; struct edge {
int v, l;
edge(int v = , int l = ) : v(v), l(l) {}
}; vector<edge> G[maxn]; void dfs(int u, int d, int p) {
deep[u] = d;
fa[u][] = p;
for(int i = ; i < G[u].size(); i++) {
int v = G[u][i].v;
if(v != p) {
cost[v] = cost[u] + G[u][i].l;
dfs(v, d + , u);
}
}
} void lca() {
for(int i = ; i <= n; i++) {
for(int j = ; ( << j) <= n; j++) {
fa[i][j] = -;
}
}
for(int j = ; ( << j) <= n; j++) {
for(int i = ; i <= n; i++) {
if(fa[i][j-] != -) {
fa[i][j] = fa[fa[i][j-]][j-];
}
}
}
} int query(int u, int v) {
if(deep[u] < deep[v]) swap(u, v);
int k;
for(k = ; ( << ( + k)) <= deep[u]; k++);
for(int i = k; i >= ; i--) {
if(deep[u] - ( << i) >= deep[v]) {
u = fa[u][i];
}
}
if(u == v) return u;
for(int i = k; i >= ; i--) {
if(fa[u][i] != - && fa[u][i] != fa[v][i]) {
u = fa[u][i];
v = fa[v][i];
}
}
return fa[u][];
} int main() {
while(~scanf("%d%d", &n, &m)) {
memset(cost, , sizeof(cost));
for(int i = ; i <= n; i++) {
G[i].clear();
}
for(int i = ; i < m; i++) {
scanf("%d%d%d%*s", &u, &v, &k);
G[u].push_back(edge(v, k));
G[v].push_back(edge(u, k));
}
dfs(, , -);
lca();
scanf("%d", &q);
while(q--) {
scanf("%d%d", &u, &v);
printf("%d\n", cost[u] + cost[v] - * cost[query(u, v)]);
}
}
return ;
}

题目链接:http://poj.org/problem?id=1330

题目:

Nearest Common Ancestors
Time Limit: 1000MS   Memory Limit: 10000K
Total Submissions: 32969   Accepted: 16750

Description

A rooted tree is a well-known data structure in computer science and engineering. An example is shown below:



In the figure, each node is labeled with an integer from {1, 2,...,16}. Node 8 is the root of the tree. Node x is an ancestor of node y if node x is in the path between the root and node y. For example, node 4 is an ancestor of node 16. Node 10 is also an ancestor of node 16. As a matter of fact, nodes 8, 4, 10, and 16 are the ancestors of node 16. Remember that a node is an ancestor of itself. Nodes 8, 4, 6, and 7 are the ancestors of node 7. A node x is called a common ancestor of two different nodes y and z if node x is an ancestor of node y and an ancestor of node z. Thus, nodes 8 and 4 are the common ancestors of nodes 16 and 7. A node x is called the nearest common ancestor of nodes y and z if x is a common ancestor of y and z and nearest to y and z among their common ancestors. Hence, the nearest common ancestor of nodes 16 and 7 is node 4. Node 4 is nearer to nodes 16 and 7 than node 8 is.

For other examples, the nearest common ancestor of nodes 2 and 3 is node 10, the nearest common ancestor of nodes 6 and 13 is node 8, and the nearest common ancestor of nodes 4 and 12 is node 4. In the last example, if y is an ancestor of z, then the nearest common ancestor of y and z is y.

Write a program that finds the nearest common ancestor of two distinct nodes in a tree.

Input

The input consists of T test cases. The number of test cases (T) is given in the first line of the input file. Each test case starts with a line containing an integer N , the number of nodes in a tree, 2<=N<=10,000. The nodes are labeled with integers 1, 2,..., N. Each of the next N -1 lines contains a pair of integers that represent an edge --the first integer is the parent node of the second integer. Note that a tree with N nodes has exactly N - 1 edges. The last line of each test case contains two distinct integers whose nearest common ancestor is to be computed.

Output

Print exactly one line for each test case. The line should contain the integer that is the nearest common ancestor.

Sample Input

2
16
1 14
8 5
10 16
5 9
4 6
8 4
4 10
1 13
6 15
10 11
6 7
10 2
16 3
8 1
16 12
16 7
5
2 3
3 4
3 1
1 5
3 5

Sample Output

4
3 思路:裸的LCA,不过要注意它的节点之间是有向的,所以需要用一个数组来储存入度,以入度为0的节点做根节点。
代码实现如下:

 #include <cstdio>
#include <vector>
#include <cstring>
using namespace std; const int maxn = 1e4 + ;
int t, n, u, v, s;
int deep[maxn], fa[maxn][], in[maxn]; vector<int> G[maxn]; void dfs(int u, int d, int p) {
deep[u] = d;
fa[u][] = p;
for(int i = ; i < G[u].size(); i++) {
int v = G[u][i];
if(v != p) {
dfs(v, d + , u);
}
}
} void lca() {
for(int i = ; i <= n; i++) {
for(int j = ; ( << j) <= n; j++) {
fa[i][j] = -;
}
}
for(int j = ; ( << j) <= n; j++) {
for(int i = ; i <= n; i++) {
if(fa[i][j-] != -) {
fa[i][j] = fa[fa[i][j-]][j-];
}
}
}
} int query(int u, int v) {
if(deep[u] < deep[v]) swap(u, v);
int k;
for(k = ; ( << ( + k)) <= deep[u]; k++);
for(int i = k; i >= ; i--) {
if(deep[u] - ( << i) >= deep[v]) {
u = fa[u][i];
}
}
if(u == v) return u;
for(int i = k; i >= ; i--) {
if(fa[u][i] != - && fa[u][i] != fa[v][i]) {
u = fa[u][i];
v = fa[v][i];
}
}
return fa[u][];
} int main() {
scanf("%d", &t);
while(t--) {
scanf("%d", &n);
for(int i = ; i <= n; i++) {
G[i].clear();
}
memset(in, , sizeof(in));
for(int i = ; i < n; i++) {
scanf("%d%d", &u, &v);
G[u].push_back(v);
G[v].push_back(u);
in[v]++;
}
for(int i = ; i <= n; i++) {
if(in[i] == ) {
s = i;
break;
}
}
dfs(s, , -);
lca();
scanf("%d%d", &u, &v);
printf("%d\n", query(u, v));
}
return ;
}


题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=4547

题目:

CD操作

Time Limit: 10000/5000 MS (Java/Others)    Memory Limit: 65535/32768 K (Java/Others)
Total Submission(s): 3035    Accepted Submission(s): 848

Problem Description
  在Windows下我们可以通过cmd运行DOS的部分功能,其中CD是一条很有意思的命令,通过CD操作,我们可以改变当前目录。
  这里我们简化一下问题,假设只有一个根目录,CD操作也只有两种方式:
  
  1. CD 当前目录名\...\目标目录名 (中间可以包含若干目录,保证目标目录通过绝对路径可达)
  2. CD .. (返回当前目录的上级目录)
  
  现在给出当前目录和一个目标目录,请问最少需要几次CD操作才能将当前目录变成目标目录?
 
Input
输入数据第一行包含一个整数T(T<=20),表示样例个数;
每个样例首先一行是两个整数N和M(1<=N,M<=100000),表示有N个目录和M个询问;
接下来N-1行每行两个目录名A B(目录名是只含有数字或字母,长度小于40的字符串),表示A的父目录是B。
最后M行每行两个目录名A B,表示询问将当前目录从A变成B最少要多少次CD操作。
数据保证合法,一定存在一个根目录,每个目录都能从根目录访问到。
 
Output
请输出每次询问的结果,每个查询的输出占一行。
 
Sample Input
2
3 1
B A
C A
B C
 
3 2
B A
C B
A C
C A
 
Sample Output
2
1
2
 
思路:由于读入是字符串,因此我们需要借助map来将它转换成数字。同时此图也是给定了节点之间的方向,需要借助入度为0的节点来做根节点。看第二组数据和第三组数据我们发现此题的一个trick:从祖宗目录到子目录操作步数只需一步,然后我们可以发现,当所要到达的目录如果是当前目录的祖宗目录时,输出cost[u]-cost[query(u,v)],否则还要+1.
代码实现如下:
 #include <map>
#include <vector>
#include <cstring>
#include <iostream>
#include <algorithm>
using namespace std; const int maxn = 1e5 + ;
int t, n, m, cnt;
string s1, s2;
int cost[maxn], deep[maxn], fa[maxn][], in[maxn]; struct edge {
int v, l;
edge (int v = , int l = ) : v (v), l (l) {}
}; vector<edge> G[maxn];
map<string, int> mp; void init() {
cnt = ;
mp.clear();
memset (in, , sizeof (in) );
memset (cost, , sizeof (cost) );
for (int i = ; i <= n; i++) {
G[i].clear();
}
} void dfs (int u, int d, int p) {
deep[u] = d;
fa[u][] = p;
for (int i = ; i < G[u].size(); i++) {
int v = G[u][i].v;
if (v != p) {
cost[v] = cost[u] + G[u][i].l;
dfs (v, d + , u);
}
}
} void lca() {
for (int i = ; i <= n; i++) {
for (int j = ; ( << j) <= n; j++) {
fa[i][j] = -;
}
}
for (int j = ; ( << j) <= n; j++) {
for (int i = ; i <= n; i++) {
if (fa[i][j - ] != -) {
fa[i][j] = fa[fa[i][j - ]][j - ];
}
}
}
} int query (int u, int v) {
if (deep[u] < deep[v])
swap (u, v);
int k;
for (k = ; ( << ( + k) ) <= deep[u]; k++);
for (int i = k; i >= ; i--) {
if (deep[u] - ( << i) >= deep[v]) {
u = fa[u][i];
}
}
if (u == v)
return u;
for (int i = k; i >= ; i--) {
if (fa[u][i] != - && fa[u][i] != fa[v][i]) {
u = fa[u][i];
v = fa[v][i];
}
}
return fa[u][];
} int main() {
ios::sync_with_stdio (false);
cin.tie ();
cin >> t;
while (t--) {
cin >> n >> m;
init();
for (int i = ; i < n; i++) {
cin >> s1 >> s2;
if(mp.find(s1) == mp.end())
mp[s1] = ++cnt;
if(mp.find(s2) == mp.end())
mp[s2] = ++cnt;
in[mp[s1]]++;
G[mp[s1]].push_back (edge (mp[s2], ) );
G[mp[s2]].push_back (edge (mp[s1], ) );
}
int s;
for (int i = ; i <= n; i++) {
if (in[i] == ) {
s = i;
}
}
dfs (s, , -);
lca();
while (m--) {
cin >> s1 >> s2;
if(query(mp[s1], mp[s2]) == mp[s2]) {
cout <<cost[mp[s1]] - cost[mp[s2]] <<endl;
} else {
cout << cost[mp[s1]] - cost[query (mp[s1], mp[s2])] + << endl;
}
}
}
return ;
}
题目:
Design the city

Time Limit: 1 Second      Memory Limit: 32768 KB

Cerror is the mayor of city HangZhou. As you may know, the traffic system of this city is so terrible, that there are traffic jams everywhere. Now, Cerror finds out that the main reason of them is the poor design of the roads distribution, and he want to change this situation.

In order to achieve this project, he divide the city up to N regions which can be viewed as separate points. He thinks that the best design is the one that connect all region with shortest road, and he is asking you to check some of his designs.

Now, he gives you an acyclic graph representing his road design, you need to find out the shortest path to connect some group of three regions.

Input

The input contains multiple test cases! In each case, the first line contian a interger N (1 < N < 50000), indicating the number of regions, which are indexed from 0 to N-1. In each of the following N-1 lines, there are three interger Ai, Bi, Li (1 < Li < 100) indicating there's a road with length Li between region Ai and region Bi. Then an interger Q (1 < Q < 70000), the number of group of regions you need to check. Then in each of the following Q lines, there are three interger Xi, Yi, Zi, indicating the indices of the three regions to be checked.

Process to the end of file.

Output

Q lines for each test case. In each line output an interger indicating the minimum length of path to connect the three regions.

Output a blank line between each test cases.

Sample Input

4
0 1 1
0 2 1
0 3 1
2
1 2 3
0 1 2
5
0 1 1
0 2 1
1 3 1
1 4 1
2
0 1 2
1 0 3

Sample Output

3
2 2
2

思路:将所给的x,y,z分别两两求一次lca,然后除2即可。
代码实现如下:
 #include <cstdio>
#include <vector>
#include <cstring>
using namespace std; const int maxn = 5e4 + ;
int n, q, u, v, k;
int cost[maxn], deep[maxn], fa[maxn][]; struct edge {
int v, l;
edge(int v = , int l = ) : v(v), l(l) {}
}; vector<edge> G[maxn]; void init() {
memset(cost, , sizeof(cost));
for(int i = ; i < maxn; i++) {
G[i].clear();
}
} void dfs(int u, int d, int p) {
deep[u] = d;
fa[u][] = p;
for(int i = ; i < G[u].size(); i++) {
int v = G[u][i].v;
if(v != p) {
cost[v] = cost[u] + G[u][i].l;
dfs(v, d + , u);
}
}
} void lca() {
for(int i = ; i < n; i++) {
for(int j = ; ( << j) < n; j++) {
fa[i][j] = -;
}
}
for(int j = ; ( << j) < n; j++) {
for(int i = ; i < n; i++) {
if(fa[i][j-] != -) {
fa[i][j] = fa[fa[i][j-]][j-];
}
}
}
} int query(int u, int v) {
if(deep[u] < deep[v]) swap(u, v);
int k;
for(k = ; ( << k) <= deep[u]; k++);
for(int i = k; i >= ; i--) {
if(deep[u] - ( << i) >= deep[v]) {
u = fa[u][i];
}
}
if(u == v) return u;
for(int i = k; i >= ; i--) {
if(fa[u][i] != - && fa[u][i] != fa[v][i]) {
u = fa[u][i];
v = fa[v][i];
}
}
return fa[u][];
} int main() {
int flag = ;
while(~scanf("%d", &n)) {
if(flag) printf("\n");
flag = ;
init();
for(int i = ; i < n; i++) {
scanf("%d%d%d", &u, &v, &k);
G[u].push_back(edge(v, k));
G[v].push_back(edge(u, k));
}
dfs(, , -);
lca();
scanf("%d", &q);
while(q--) {
scanf("%d%d%d", &u, &v, &k);
printf("%d\n", (cost[u] + cost[v] - * cost[query(u, v)] + cost[u] + cost[k] - * cost[query(u, k)] + cost[v] + cost[k] - * cost[query(v, k)]) / );
}
}
return ;
}

至此感觉自己的LCA应该算是入门了,深入刷难题暑假再开始,毕竟现在要开始准备期末了,免得上学期专业课满绩点,高代全年级第一,这学期全部挂科然后挨骂Σ( ° △ °|||)︴

LCA入门题集小结的更多相关文章

  1. poj 1330(RMQ&LCA入门题)

    传送门:Problem 1330 https://www.cnblogs.com/violet-acmer/p/9686774.html 参考资料: http://dongxicheng.org/st ...

  2. POJ1330(LCA入门题)

    Nearest Common Ancestors Time Limit: 1000MS   Memory Limit: 10000K Total Submissions: 23388   Accept ...

  3. lca入门———树上倍增法(博文内含例题)

    倍增求LCA: father[i][j]表示节点i往上跳2^j次后的节点 可以转移为 father[i][j]=father[father[i][j-1]][j-1] 整体思路: 先比较两个点的深度, ...

  4. poj 2524:Ubiquitous Religions(并查集,入门题)

    Ubiquitous Religions Time Limit: 5000MS   Memory Limit: 65536K Total Submissions: 23997   Accepted:  ...

  5. hrbustoj 1073:病毒(并查集,入门题)

    病毒Time Limit: 1000 MS Memory Limit: 65536 KTotal Submit: 719(185 users) Total Accepted: 247(163 user ...

  6. ACM题集以及各种总结大全(转)

    ACM题集以及各种总结大全! 虽然退役了,但是整理一下,供小弟小妹们以后切题方便一些,但由于近来考试太多,顾退役总结延迟一段时间再写!先写一下各种分类和题集,欢迎各位大牛路过指正. 一.ACM入门 关 ...

  7. ACM题集以及各种总结大全!

    ACM题集以及各种总结大全! 虽然退役了,但是整理一下,供小弟小妹们以后切题方便一些,但由于近来考试太多,顾退役总结延迟一段时间再写!先写一下各种分类和题集,欢迎各位大牛路过指正. 一.ACM入门 关 ...

  8. Codevs 3287 货车运输 2013年NOIP全国联赛提高组(带权LCA+并查集+最大生成树)

    3287 货车运输 2013年NOIP全国联赛提高组 时间限制: 1 s 空间限制: 128000 KB 题目等级 : 钻石 Diamond 传送门 题目描述 Description A 国有 n 座 ...

  9. 数位dp题集

    题集见大佬博客 不要62 入门题,检验刚才自己有没有看懂 注意一些细节. 的确挺套路的 #include<bits/stdc++.h> #define REP(i, a, b) for(r ...

随机推荐

  1. LintCode-41.最大子数组

    最大子数组 给定一个整数数组,找到一个具有最大和的子数组,返回其最大和. 注意事项 子数组最少包含一个数 样例 给出数组[−2,2,−3,4,−1,2,1,−5,3],符合要求的子数组为[4,−1,2 ...

  2. 如何取得dbgrid中未保存(post)的值(50分)

    比如说处在编辑状态时,想取得当前记录值 Dataset.fields[0].Value 就是当前值:Dataset.fields[0].OldValue 就是原始值. 呵呵,我指得是在编辑时,就是按键 ...

  3. 能选择日期范围js控件

    html页面中使用日期控件是常有的事,好控件能使用开发变的快捷,下面是在开发过程中发现的几款日期控件,比较不错,收藏 1.基于bootstrap的jQuery日期范围选择插件 2.jQuery多功能日 ...

  4. 【bzoj5094】硬盘检测 乱搞

    题目描述 已知从 $n$ 个不同的32位无符号整数中随机选 $m=10000$ 次所得的结果,求可能性最大的 $n$ ,其中 $n=10^k,1\le k\le 7$. 输入 第一行包含一个正整数m( ...

  5. 前端基础:HTML标签(下)

    前端基础HTML标签(下) 1.表单 表单的功能主要用于向服务器传输数据,从而实现客户端与Web服务器的交互.表单能够包含input系列标签,比如:文本字段.复选框.单选按钮.提交按钮等:表单还包含t ...

  6. HTML5语义元素总结

    HTML5语义元素 语义=意义 语义元素=元素的意义   什么事语义元素? 一个语义元素能够清楚的描述其意义给浏览器和开发者. 无语义 元素实例:div.span.无需考虑内容. 语义 元素实例:fo ...

  7. BZOJ4771 七彩树(dfs序+树上差分+主席树)

    考虑没有深度限制怎么做.显然的做法是直接转成dfs序上主席树,但如果拓展到二维变成矩形数颜色数肯定没法做到一个log. 另一种做法是利用树上差分.对于同种颜色的点,在每个点处+1,dfs序相邻点的lc ...

  8. BZOJ4869 六省联考2017相逢是问候(线段树+欧拉函数)

    由扩展欧拉定理,a^(a^(a^(……^x)))%p中x作为指数的模数应该是φ(φ(φ(φ(……p)))),而p取log次φ就会变为1,也即每个位置一旦被修改一定次数后就会变为定值.线段树维护区间剩余 ...

  9. Hadoop——HDFS的构架

    在使用一个工具之前,应该先对它的机制.组成等有深入的了解,以后才会更好的使用它.下面来介绍一下什么是HDFS,以及他的构架是什么样的. 1.什么是HDFS? Hadoop主要是用于进行大数据处理,那么 ...

  10. [洛谷P4721]【模板】分治 FFT_求逆

    题目大意:给定长度为$n-1$的数组$g_{[1,n)}$,求$f_{[0,n)}$,要求: $$f_i=\sum_{j=1}^if_{i-j}g_j\\f_0=1$$ 题解:分治$FFT$博客,发现 ...