Touristis(LCA)

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.

输入

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.

输出

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;
}
如果有不对的地方,还请各位大佬指正。


猜你喜欢

转载自www.cnblogs.com/loganacmer/p/11297426.html
lca