E. Kamil and Making a Stream 区间gcd

E. Kamil and Making a Stream

这个题目要用到一个结论,就是区间一个区间长度为n的不同的gcd不会超过logn 个,

其实就是知道这个题目可以暴力就好了。

然后就是对于每一个节点,我都存从祖先到这个节点的所有的gcd,用一个vector存下来。

然后因为这个vector的size 不会很大,所以就可以直接暴力往下转移。

#include <cstdio>
#include <cstring>
#include <cstdlib>
#include <queue>
#include <bitset>
#include <string>
#include <algorithm>
#include <iostream>
#include <map>
#define inf 0x3f3f3f3f
#define inf64 0x3f3f3f3f3f3f3f3f
using namespace std;
const int maxn = 1e5 + 10;
const int mod = 1e9 + 7;
typedef long long ll;
typedef pair<ll, ll> P;
vector<P>val[maxn];
vector<int>G[maxn];
ll a[maxn], ans;

void add(int u, int v) {
    G[u].push_back(v);
    G[v].push_back(u);
}

ll gcd(ll a, ll b) {
    return b == 0 ? a : gcd(b, a%b);
}

void dfs(int u, int pre,int dep) {
    for (int i = 0; i < G[u].size(); i++) {
        int v = G[u][i];
        if (v == pre) continue;
        for (int j = 0; j < val[u].size(); j++) {
            P now = val[u][j];
            ll ans = gcd(now.first, a[v]);
            int len = val[v].size();
            if (len == 0 || ans != val[v][len - 1].first) val[v].push_back(make_pair(ans, now.second));
        }
        val[v].push_back(make_pair(a[v], dep + 1));
        dfs(v, u, dep + 1);
    }
}

void dfs1(int u, int pre) {
    for (int i = 1; i < val[u].size(); i++) {
        ans += (val[u][i].second - val[u][i - 1].second) % mod*val[u][i - 1].first%mod;
        ans %= mod;
    }
    ans += a[u] % mod;
    ans %= mod;
    for (int i = 0; i < G[u].size(); i++) {
        int v = G[u][i];
        if (v == pre) continue;
        dfs1(v, u);
    }
}
/*
void dfsprint(int u, int pre) {
    for (int i = 0; i < val[u].size(); i++) {
        printf("ww u=%d %lld %lld
", u, val[u][i].first, val[u][i].second);
    }
    for (int i = 0; i < G[u].size(); i++) {
        int v = G[u][i];
        if (v == pre) continue;
        dfsprint(v, u);
    }
}
*/

int main() {
    int n;
    scanf("%d", &n);
    for (int i = 1; i <= n; i++) scanf("%lld", &a[i]);
    for (int i = 1; i < n; i++) {
        int u, v;
        scanf("%d%d", &u, &v);
        add(u, v);
    }
    val[1].push_back(make_pair(a[1], 1));
    dfs(1, -1, 1);
    ans = 0;
    dfs1(1, -1);
//    dfsprint(1, -1);
    printf("%lld
", ans);
    return 0;
}
 
View Code
原文地址:https://www.cnblogs.com/EchoZQN/p/11596062.html