CF986E Prince's Problem 题解
*2800,不是很难,但有点卡常。
考虑
对
枚举每一个
由于
容易树上差分将询问变为一个点到根数颜色,离线之后一次 DFS 动态维护前缀和数组并统计答案即可。然而这个做法复杂度比较大,大概是
#pragma GCC optimize("-Ofast,fast-math,-inline")
#pragma GCC target("avx,sse,sse2,sse3,popcnt")
#pragma pack(1)
#include <iostream>
#include <cstdio>
#include <algorithm>
#include <cmath>
#include <cstring>
#include <string>
#include <vector>
#include <cstdlib>
using namespace std;
const int N = 1e5 + 5, MOD = 1e9 + 7;
vector<pair<int, int> > v[N];
int n, a[N], q;
vector<int> G[N];
struct Query
{
int u, v, w;
Query(int _u, int _v, int _w) : u(_u), v(_v), w(_w) {}
Query() = default;
}p[N];
int nfa[N][21], dep[N];
void dfs(int u, int f)
{
nfa[u][0] = f;
dep[u] = dep[f] + 1;
for (auto& j : G[u])
{
if (j ^ f) dfs(j, u);
}
}
vector<pair<int, int> > qre[N];
int ans[N];
int rid[N * 8];
int sum[N * 8][25];
long long qpow(long long a, long long b)
{
long long res = 1, base = a;
while (b)
{
if (b & 1LL) res = res * base % MOD;
base = base * base % MOD;
b >>= 1LL;
}
return res;
}
int xx[N * 55], kkk[N * 55];
struct Nqe
{
int sgn, id;
Nqe() = default;
Nqe(int sgn, int id)
: sgn(sgn), id(id)
{
}
};
vector<Nqe> each[N];
int LCA(int u, int v)
{
if (u == v) return u;
if (dep[u] < dep[v]) swap(u, v);
int k = dep[u] - dep[v], c = 0;
while (k)
{
if (k & 1) u = nfa[u][c];
k >>= 1;
c++;
}
if (u == v) return u;
for (int i = 20; i >= 0; i--)
{
if (nfa[u][i] != nfa[v][i]) u = nfa[u][i], v = nfa[v][i];
}
return nfa[u][0];
}
int res[N * 55];
int idx;
void redfs(int u, int f)
{
for (auto& j : v[u])
{
sum[j.first][j.second]++;
}
for (auto& j : each[u])
{
res[j.id] += j.sgn * sum[xx[j.id]][kkk[j.id]];
}
for (auto& j : G[u])
{
if (j ^ f) redfs(j, u);
}
for (auto& j : v[u])
{
sum[j.first][j.second]--;
}
}
int L[N], R[N];
int k2[N * 55];
int main()
{
ios::sync_with_stdio(0), cin.tie(0);
cin >> n;
vector<int> divs;
int pu = 0;
for (int i = 1; i < n; i++)
{
int u, v;
cin >> u >> v;
if (!pu) pu = u;
G[u].emplace_back(v);
G[v].emplace_back(u);
}
for (int i = 1; i <= n; i++)
{
cin >> a[i];
int ra = a[i];
for (int j = 2; 1LL * j * j <= ra; j++)
{
if (ra % j == 0)
{
int c = 0;
while (ra % j == 0) ra /= j, c++;
v[i].emplace_back(make_pair(j, c));
}
}
if (ra != 1) v[i].emplace_back(make_pair(ra, 1));
sort(v[i].begin(), v[i].end());
for (auto& j : v[i]) divs.emplace_back(j.first);
}
dfs(1, 0);
for (int i = 1; i <= 20; i++)
{
for (int j = 1; j <= n; j++) nfa[j][i] = nfa[nfa[j][i - 1]][i - 1];
}
cin >> q;
for (int i = 1; i <= q; i++)
{
ans[i] = 1;
int u, v, w;
cin >> u >> v >> w;
p[i] = Query(u, v, w);
int ra = w;
for (int j = 2; 1LL * j * j <= ra; j++)
{
if (ra % j == 0)
{
int c = 0;
while (ra % j == 0) ra /= j, c++;
qre[i].emplace_back(make_pair(j, c));
}
}
if (ra != 1) qre[i].emplace_back(make_pair(ra, 1));
sort(qre[i].begin(), qre[i].end());
for (auto& j : qre[i]) divs.emplace_back(j.first);
}
sort(divs.begin(), divs.end());
divs.erase(unique(divs.begin(), divs.end()), divs.end());
for (auto& j : divs)
{
int rj = j;
int nj = lower_bound(divs.begin(), divs.end(), j) - divs.begin() + 1;
rid[nj] = rj;
}
for (int i = 1; i <= n; i++)
{
for (auto& j : v[i]) j.first = lower_bound(divs.begin(), divs.end(), j.first) - divs.begin() + 1;
}
for (int i = 1; i <= q; i++)
{
for (auto& j : qre[i]) j.first = lower_bound(divs.begin(), divs.end(), j.first) - divs.begin() + 1;
}
for (int i = 1; i <= q; i++)
{
int u = p[i].u, vv = p[i].v;
int l = LCA(u, vv);
L[i] = idx + 1;
for (auto& j : qre[i])
{
long long nowres = 1LL;
for (int k = 0; k <= 23; k++)
{
if (nowres > (long long)1e7) break;
nowres *= rid[j.first];
idx++;
xx[idx] = j.first, kkk[idx] = k;
each[u].emplace_back(Nqe(1, idx));
each[vv].emplace_back(Nqe(1, idx));
each[l].emplace_back(Nqe(-2, idx));
k2[idx] = min(k, j.second);
for (auto& g : v[l])
{
if (g == make_pair(j.first, k))
{
ans[i] = 1LL * ans[i] * qpow(rid[j.first], min(j.second, k)) % MOD;
}
}
}
}
R[i] = idx; // 1
}
redfs(1, 0);
for (int i = 1; i <= q; i++)
{
for (int j = L[i]; j <= R[i]; j++)
{
ans[i] = (1LL * ans[i] * qpow(qpow(rid[xx[j]], k2[j]), res[j])) % MOD;
}
cout << ans[i] << "\n";
}
return 0;
}
分类:
题解
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 分享一个免费、快速、无限量使用的满血 DeepSeek R1 模型,支持深度思考和联网搜索!
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· ollama系列01:轻松3步本地部署deepseek,普通电脑可用
· 25岁的心里话
· 按钮权限的设计及实现