• CodeForces


    Description

    给一棵树,每个点有点权 (a_i) ,每次给 (u,v,x) ,求 (u)(v) 路径上每个点的点权与 (x)(gcd) 的积。

    (n,mle 10^5,1le a_ile 10^7)

    Solution

    离线,答案相当与四条从根出发的链拼起来,分解质因数。

    #include<bits/stdc++.h>
    using namespace std;
    
    template <class T> void read(T &x) {
    	x = 0; bool flag = 0; char ch = getchar(); for (; ch < '0' || ch > '9'; ch = getchar()) flag |= ch == '-';
    	for (; ch >= '0' && ch <= '9'; ch = getchar()) x = x * 10 + ch - 48; flag ? x = ~x + 1 : 0;
    }
    
    //#pragma GCC diagnostic error "-std=c++14"
    
    #define N 100010
    #define rep(i, a, b) for (auto i = (a); i <= (b); ++i)
    #define drp(i, a, b) for (auto i = (a); i >= (b); --i)
    #define P 1000000007
    
    bool notPri[10000010];
    int pri[664580 + 10], priCnt;
    
    void init(int n) {
    	int m = sqrt(n + 0.5);
    	rep(i, 2, m) if (!notPri[i]) for (int j = i * i; j <= n; j += i) notPri[j] = 1;
    	rep(i, 2, n) if (!notPri[i]) pri[++priCnt] = i;
    }
    
    vector<int> g[N];
    
    int fa[N][18], dep[N];
    void dfs(int u) {
    	rep(i, 1, 17) fa[u][i] = fa[fa[u][i - 1]][i - 1];
    	for (int v : g[u]) if (v ^ fa[u][0]) fa[v][0] = u, dep[v] = dep[u] + 1, dfs(v);
    }
    
    int getLca(int u, int v) {
    	if (dep[u] < dep[v]) swap(u, v);
    	drp(i, 17, 0) if (dep[fa[u][i]] >= dep[v]) u = fa[u][i]; if (u == v) return u;
    	drp(i, 17, 0) if (fa[u][i] ^ fa[v][i]) u = fa[u][i], v = fa[v][i]; return fa[u][0];
    }
    
    struct Data {
    	int x, id;
    	bool type;
    	Data(int x = 0, int id = 0, bool type = 0) : x(x), id(id), type(type) {}
    };
    
    vector<Data> q[N];
    
    int qpow(int x, int k) {
    	int ret = 1;
    	for (; k; k >>= 1, x = 1ll * x * x % P) if (k & 1) ret = 1ll * ret * x % P;
    	return ret;
    }
    
    int a[N], ans[N], cnt[664580 + 10][25];
    
    void update(int val, int del) {
    	for (int i = 1; 1ll * pri[i] * pri[i] <= val; ++i) if (val % pri[i] == 0) {
    		int p = 0;
    		for (; val % pri[i] == 0; val /= pri[i], ++p);
    		cnt[i][p] += del;
    	}
    	if (val != 1) cnt[lower_bound(pri + 1, pri + 1 + priCnt, val) - pri][1] += del;
    }
    
    int query(int val) {
    	int ret = 1;
    	for (int i = 1; 1ll * pri[i] * pri[i] <= val; ++i) if (val % pri[i] == 0) {
    		int p = 0, t = 0;
    		for (; val % pri[i] == 0; val /= pri[i], ++p);
    		rep(j, 1, p) t += cnt[i][j] * j;
    		rep(j, p + 1, 24) t += cnt[i][j] * p;
    		ret = 1ll * ret * qpow(pri[i], t) % P;
    	}
    	if (val == 1) return ret;
    	int pos = lower_bound(pri + 1, pri + 1 + priCnt, val) - pri;
    	int t = 0;
    	rep(i, 1, 24) t += cnt[pos][i];
    	return 1ll * ret * qpow(val, t) % P;
    }
    
    void solve(int u) {
    	update(a[u], 1);
    	for (auto t : q[u]) {
    		if (t.type) ans[t.id] = 1ll * ans[t.id] * query(t.x) % P;
    		else ans[t.id] = 1ll * ans[t.id] * qpow(query(t.x), P - 2) % P;
    	}
    	for (int v : g[u]) if (v != fa[u][0]) solve(v);
    	update(a[u], -1);
    }
    
    #define pb push_back
    
    int main() {
    	init(10000000);
    	int n, m; read(n);
    	rep(i, 2, n) {
    		int u, v; read(u), read(v);
    		g[u].pb(v), g[v].pb(u);
    	}
    	dep[1] = 1; dfs(1);
    	rep(i, 1, n) read(a[i]);
    	read(m);
    	rep(i, 1, m) {
    		int u, v, x; read(u), read(v), read(x);
    		int lca = getLca(u, v);
    		ans[i] = 1;
    		q[u].pb(Data(x, i, 1)), q[v].pb(Data(x, i, 1)), q[lca].pb(Data(x, i, 0));
    		if (lca != 1) q[fa[lca][0]].pb(Data(x, i, 0));
    	}
    	solve(1);
    	rep(i, 1, m) printf("%d
    ", ans[i]);
    	return 0;
    }
    
    
  • 相关阅读:
    python3中的匿名函数
    python3拆包、元组、字典
    python3函数中的不定长参数
    python3中的缺省参数和命名参数
    python3字符串的常见操作
    用python使用Mysql数据库
    Git常用命令
    Linux下配置Nginx(在root的/etc/rc.local里配置开机启动功能http://tengine.taobao.org/)
    大数据项目中js中代码和java中代码(解决Tomcat打印日志中文乱码)
    java中时间
  • 原文地址:https://www.cnblogs.com/aziint/p/9752455.html
Copyright © 2020-2023  润新知