Tourists
时间限制: 5 Sec 内存限制: 64 MB
题目描述
In Tree City, there are n tourist attractions uniquely labeled 1 to n. The attractions are connected by a set of n − 1 bidirectional roads in such a way that a tourist can get from any attraction to any other using some path of roads.
You are a member of the Tree City planning committee. After much research into tourism, your committee has discovered a very interesting fact about tourists: they LOVE number theory! A tourist who visits an attraction with label x will then visit another attraction with label y if y > x and y is a multiple of x. Moreover, if the two attractions are not directly connected by a road thetourist will necessarily visit all of the attractions on the path connecting x and y, even if they aren’t multiples of x. The number of attractions visited includes x and y themselves. Call this the length of a path.
Consider this city map:
Here are all the paths that tourists might take, with the lengths for each:
1 → 2 = 4, 1 → 3 = 3, 1 → 4 = 2, 1 → 5 = 2, 1 → 6 = 3, 1 → 7 = 4,
1 → 8 = 3, 1 → 9 = 3, 1 → 10 = 2, 2 → 4 = 5, 2 → 6 = 6, 2 → 8 = 2,
2 → 10 = 3, 3 → 6 = 3, 3 → 9 = 3, 4 → 8 = 4, 5 → 10 = 3
To take advantage of this phenomenon of tourist behavior, the committee would like to determine the number of attractions on paths from an attraction x to an attraction y such that y > x and y is a multiple of x. You are to compute the sum of the lengths of all such paths. For the example above, this is: 4 + 3 + 2 + 2 + 3 + 4 + 3 + 3 + 2 + 5 + 6 + 2 + 3 + 3 + 3 + 4 + 3 = 55.
You are a member of the Tree City planning committee. After much research into tourism, your committee has discovered a very interesting fact about tourists: they LOVE number theory! A tourist who visits an attraction with label x will then visit another attraction with label y if y > x and y is a multiple of x. Moreover, if the two attractions are not directly connected by a road thetourist will necessarily visit all of the attractions on the path connecting x and y, even if they aren’t multiples of x. The number of attractions visited includes x and y themselves. Call this the length of a path.
Consider this city map:
1 → 2 = 4, 1 → 3 = 3, 1 → 4 = 2, 1 → 5 = 2, 1 → 6 = 3, 1 → 7 = 4,
1 → 8 = 3, 1 → 9 = 3, 1 → 10 = 2, 2 → 4 = 5, 2 → 6 = 6, 2 → 8 = 2,
2 → 10 = 3, 3 → 6 = 3, 3 → 9 = 3, 4 → 8 = 4, 5 → 10 = 3
To take advantage of this phenomenon of tourist behavior, the committee would like to determine the number of attractions on paths from an attraction x to an attraction y such that y > x and y is a multiple of x. You are to compute the sum of the lengths of all such paths. For the example above, this is: 4 + 3 + 2 + 2 + 3 + 4 + 3 + 3 + 2 + 5 + 6 + 2 + 3 + 3 + 3 + 4 + 3 = 55.
输入
Each input will consist of a single test case. Note that your program may be run multiple times on different inputs. The ?rst line of input will consist of an integer n (2 ≤ n ≤ 200,000) indicating the number of attractions. Each of the following n−1 lines will consist of a pair of space-separated
integers i and j (1 ≤ i < j ≤ n), denoting that attraction i and attraction j are directly connected by a road. It is guaranteed that the set of attractions is connected.
integers i and j (1 ≤ i < j ≤ n), denoting that attraction i and attraction j are directly connected by a road. It is guaranteed that the set of attractions is connected.
输出
Output a single integer, which is the sum of the lengths of all paths between two attractions x and y such that y > x and y is a multiple of x.
样例输入
10
3 4
3 7
1 4
4 6
1 10
8 10
2 8
1 5
4 9
题目思路:
就是求最小公共祖先,然后计算祖先到这两个点的距离相加,用树上倍增和targan算法都能做。
这里我用Targan实现,先筛出每个询问保存,然后用targan求祖先,并用一个d数组保存此点到树根的距离。
#include<bits/stdc++.h> #define ll long long using namespace std; ll f[200010],d[200010],vis[200010],ans,n; vector<ll> v[200010],ask[200010]; int find(int x) { if(f[x]==x) return x; return f[x] = find(f[x]); } void tarjan(int x) { vis[x] = 1; for(int i = 0;i<v[x].size();i++) { if(!vis[v[x][i]]) { d[v[x][i]] = d[x]+1; tarjan(v[x][i]); f[v[x][i]] = x; } } for(int i = 0;i<ask[x].size();i++) { if(vis[ask[x][i]]) ans+=d[x]+d[ask[x][i]]-2*d[find(ask[x][i])]+1; else ask[ask[x][i]].push_back(x); } } int main() { int a,b; cin>>n; for(int i = 0;i<=n;i++) f[i] = i; for(int i = 1;i<n;i++) for(int j = i*2;j<=n;j+=i) ask[i].push_back(j); for(int i = 1;i<n;i++) { scanf("%d%d",&a,&b); v[a].push_back(b); v[b].push_back(a); } d[1] = 1; tarjan(1); cout<<ans; return 0; }
如果有不对的地方,还请各位大佬指正。