[Codeforces 986E] Prince's Problem
[题目链接]
https://codeforces.com/contest/986/problem/E
[算法]
X到Y的路径积 , 可以转化为X到根的路径积乘Y到根的路径积 , 除以LCA到根的路径积 , 再除以LCA父节点到根的路径积
考虑如何计算根到X路径上每个点与Value的GCD之积
不妨对于每个质数P开一个数组cnt[] , 表示根到当前节点P^i有多少个 , 我们可以在DFS的过程中维护这个数组
将询问离线即可
时间复杂度 : O(V + NlogN + QlogV^2)
[代码]
#include<bits/stdc++.h>
using namespace std;
#define MAXLOG 30
const int P = 1e9 + ;
const int MAXN = 1e5 + ;
const int MAXP = 1e6 + ;
const int MAXV = 1e7 + ; struct edge
{
int to , nxt;
} e[MAXN << ];
struct info
{
int value , home;
bool type;
} ;
int tot , n , t;
int a[MAXN],depth[MAXN],prime[MAXP],head[MAXN],ans[MAXN],f[MAXV];
int cnt[MAXP][MAXLOG],anc[MAXN][MAXLOG];
vector< info > q[MAXN]; template <typename T> inline void chkmax(T &x,T y) { x = max(x,y); }
template <typename T> inline void chkmin(T &x,T y) { x = min(x,y); }
template <typename T> inline void read(T &x)
{
T f = ; x = ;
char c = getchar();
for (; !isdigit(c); c = getchar()) if (c == '-') f = -f;
for (; isdigit(c); c = getchar()) x = (x << ) + (x << ) + c - '';
x *= f;
}
inline void addedge(int u,int v)
{
t++;
e[t] = (edge){v,head[u]};
head[u] = t;
}
inline int exp_mod(int a,int n)
{
int res = , b = a;
while (n > )
{
if (n & ) res = 1ll * res * b % P;
b = 1ll * b * b % P;
n >>= ;
}
return res;
}
inline int inv(int x) { return exp_mod(x,P - ); }
inline void dfs(int u,int fa)
{
depth[u] = depth[fa] + ;
for (int i = ; i < MAXLOG; i++)
{
if (depth[u] <= ( << i)) break;
anc[u][i] = anc[anc[u][i - ]][i - ];
}
for (int i = head[u]; i; i = e[i].nxt)
{
int v = e[i].to;
if (v == fa) continue;
anc[v][] = u;
depth[v] = depth[u] + ;
dfs(v,u);
}
}
inline int lca(int u,int v)
{
if (depth[u] > depth[v]) swap(u,v);
for (int i = MAXLOG - ; i >= ; i--)
{
if (depth[anc[v][i]] >= depth[u])
v = anc[v][i];
}
if (u == v) return u;
for (int i = MAXLOG - ; i >= ; i--)
{
if (anc[u][i] != anc[v][i])
u = anc[u][i] , v = anc[v][i];
}
return anc[u][];
}
inline void modify(int x,int delta)
{
for (int i = ; 1ll * prime[i] * prime[i] <= x; i++)
{
if (x % prime[i] == )
{
int p = ;
while (x % prime[i] == )
{
x /= prime[i];
p++;
}
cnt[i][p] += delta;
}
}
if (x != )
{
int pos = lower_bound(prime + ,prime + tot + ,x) - prime;
cnt[pos][] += delta;
}
}
inline int query(int x)
{
int ret = ;
for (int i = ; 1ll * prime[i] * prime[i] <= x; i++)
{
if (x % prime[i] == )
{
int p = ;
while (x % prime[i] == )
{
p++;
x /= prime[i];
}
int s = ;
for (int j = ; j <= p; j++) s += cnt[i][j] * j;
for (int j = p + ; j < MAXLOG; j++) s += cnt[i][j] * p;
ret = 1ll * ret * exp_mod(prime[i],s) % P;
}
}
if (x != )
{
int pos = lower_bound(prime + ,prime + tot + ,x) - prime;
int s = ;
for (int i = ; i < MAXLOG; i++) s += cnt[pos][i];
ret = 1ll * ret * exp_mod(x,s) % P;
}
return ret;
} inline void solve(int u,int fa)
{
modify(a[u],);
for (unsigned i = ; i < q[u].size(); i++)
{
if (q[u][i].type) ans[q[u][i].home] = 1ll * ans[q[u][i].home] * query(q[u][i].value) % P;
else ans[q[u][i].home] = 1ll * ans[q[u][i].home] * inv(query(q[u][i].value)) % P;
}
for (int i = head[u]; i; i = e[i].nxt)
{
int v = e[i].to;
if (v == fa) continue;
solve(v,u);
}
modify(a[u],-);
} int main()
{ read(n);
for (int i = ; i < MAXV; i++)
{
if (!f[i])
{
f[i] = i;
prime[++tot] = i;
}
for (int j = ; j <= tot; j++)
{
int tmp = i * prime[j];
if (tmp >= MAXV) break;
f[tmp] = prime[j];
if (prime[j] == f[i]) break;
}
}
for (int i = ; i < n; i++)
{
int u , v;
read(u); read(v);
addedge(u,v);
addedge(v,u);
}
dfs(,);
for (int i = ; i <= n; i++) read(a[i]);
int Q;
read(Q);
for (int i = ; i <= Q; i++)
{
int u , v , x;
read(u); read(v); read(x);
int Lca = lca(u,v);
q[u].push_back((info){x,i,true});
q[v].push_back((info){x,i,true});
q[Lca].push_back((info){x,i,false});
if (Lca != ) q[anc[Lca][]].push_back((info){x,i,false});
ans[i] = ;
}
solve(,);
for (int i = ; i <= Q; i++) printf("%d\n",ans[i]); return ; }
[Codeforces 986E] Prince's Problem的更多相关文章
- Codeforces 986E - Prince's Problem(树上前缀和)
题面传送门 题意: 有一棵 \(n\) 个节点的树,点上有点权 \(a_i\),\(q\) 组询问,每次询问给出 \(u,v,w\),要求: \(\prod\limits_{x\in P(u,v)}\ ...
- [codeforces 528]B. Clique Problem
[codeforces 528]B. Clique Problem 试题描述 The clique problem is one of the most well-known NP-complete ...
- codeforces.com/contest/325/problem/B
http://codeforces.com/contest/325/problem/B B. Stadium and Games time limit per test 1 second memory ...
- Codeforces 442B Andrey and Problem(贪婪)
题目链接:Codeforces 442B Andrey and Problem 题目大意:Andrey有一个问题,想要朋友们为自己出一道题,如今他有n个朋友.每一个朋友想出题目的概率为pi,可是他能够 ...
- CodeForces 867B Save the problem
B. Save the problem! http://codeforces.com/contest/867/problem/B time limit per test 2 seconds memor ...
- Codeforces 776D The Door Problem
题目链接:http://codeforces.com/contest/776/problem/D 把每一个钥匙拆成两个点${x,x+m}$,分别表示选不选这把钥匙. 我们知道一扇门一定对应了两把钥匙. ...
- codeforces 803G Periodic RMQ Problem
codeforces 803G Periodic RMQ Problem 题意 长度为\(1e5\)的数组复制\(1e4\)次,对新的数组进行区间覆盖和区间最小值查询两种操作,操作次数\(1e5\). ...
- 【codeforces 527D】Clique Problem
[题目链接]:http://codeforces.com/contest/527/problem/D [题意] 一维线段上有n个点 每个点有坐标和权值两个域分别为xi,wi; 任意一对点(i,j) 如 ...
- 【codeforces 793C】Mice problem
[题目链接]:http://codeforces.com/contest/793/problem/C [题意] 给你每个点x轴移动速度,y轴移动速度; 问你有没有某个时刻,所有的点都"严格& ...
随机推荐
- PHP面向对象设计五大原则(SOLID)梳理总结
PHP设计原则梳理,参考<PHP核心技术与最佳实践>.<敏捷开发原则.模式与实践>,文章PHP面向对象设计的五大原则.设计模式原则SOLID 单一职责原则(Single Res ...
- ResNet实战
目录 Res Block ResNet18 Out of memory # Resnet.py #!/usr/bin/env python # -*- coding:utf-8 -*- import ...
- LeetCode 121. Best Time to Buy and Sell Stock (stock problem)
Say you have an array for which the ith element is the price of a given stock on day i. If you were ...
- Python模块基础
概念: 在Python中,一个.py文件就称之为一个模块(Module) 好处: 1. 提高可维护性 2. 可重用 3. 避免函数名.变量名冲突. 每个模块有独立的命名空间,因此相同名字的函数和变量完 ...
- JPA中映射关系详细说明(一对多,多对一,一对一、多对多)、@JoinColumn、mappedBy说明
JPA中的映射关系 jpa中维护one to one ,one to many, many to one ,many to many 四种映射关系. 在每个关系中,双方中的一方在其表中拥有连接列.那么 ...
- 将windows应用程序注册为windows服务
@echo off::设置服务名称set service_name=ServiceManagement ::设置服务描述set service_description=文件安全上传服务 ::设置服务程 ...
- JDBC中的批处理
以下内容引用自http://wiki.jikexueyuan.com/project/jdbc/batch-processing.html: 批处理是指将关联的SQL语句组合成一个批处理,并将他们当成 ...
- 【SQL Server 学习系列】-- 收缩数据库文件大小
USE WebExam; GO ALTER DATABASE WebExam SET RECOVERY SIMPLE; GO -- 收缩文件到 1 MB. ); GO ALTER DATABASE W ...
- Android GIS开发系列-- 入门季(8) Json与Geometry的相互转换
在Android中json数据十分普遍,也很实用,在Arcgis中也同样支持Json数据,Json与Geometry可以相互转换,达到我们想要的数据. 一.Geometry转换成Json数据 这个实现 ...
- 条款十七: 在operator=中检查给自己赋值的情况
在赋值运算符中要特别注意可能出现别名的情况,其理由基于两点.其中之一是效率.如果可以在赋值运算符函数体的首部检测到是给自己赋值,就可以立即返回,从而可以节省大量的工作,否则必须去实现整个赋值操作. 另 ...