题目链接:

https://jzoj.net/senior/#main/show/6086

题目:

题解:

  • 一群数字的最小公倍数就是对它们质因数集合中的每个质因数的指数取$max$然后相乘
  • 这样的子树查询一般都与$dfs$序有关
  • 不妨把一个质因数$p$拆分成$p^1,p^2,p^3...$这样若干种颜色,每种颜色对答案的贡献都是$p$
  • 我们从另一个角度来考虑如何处理“不同的数”。先不管深度,考虑两个点权相等的节点$u$和$v$,点权为$val$,他们自己的贡献是使得所有子树内包含他的节点答案乘以$val$,现在考虑重复了的贡献,同时包含$u$和$v$的节点答案被乘了两次,即包含$lca(u,v)$的节点答案需要被除去一个$val$。
  • 多个节点的时候,只需按$dfs$序排序,相邻两个的$lca$处除即可。现在我们要考虑深度,只需要将询问离线并按深度排序,节点按深度排序后一个一个加入即可。维护点权相同的点可以用$set$,维护$dfs$序用线段树。这是一个很经典的做法
  • 在线的话,把线段树可持久化即可

代码:

#include<algorithm>
#include<cstring>
#include<cstdio>
#include<iostream>
#include<cmath>
#include<set>
#include<map>
using namespace std;
typedef long long ll; const int N=1e5+;
const int M=1e7+;
const int mo=;
int n,tot;
int a[N],head[N];
set <int> s[N*];
map<int,int>hsh;
struct EDGE
{
int to,nxt;
}edge[N<<];
inline int read()
{
char ch=getchar();int s=,f=;
while (ch<''||ch>'') {if (ch=='-') f=-;ch=getchar();}
while (ch>=''&&ch<='') {s=(s<<)+(s<<)+ch-'';ch=getchar();}
return s*f;
}
int cnt;
int prime[M],mn[M],vis[M];
void pre()
{
mn[]=;
for (int i=;i<M;i++)
{
if (!vis[i]) prime[++cnt]=i,mn[i]=i;
for (int j=;j<=cnt&&prime[j]*i<M;j++)
{
vis[prime[j]*i]=;mn[prime[j]*i]=prime[j];
if (i%prime[j]==) break;
}
}
}
int qpow(int a,int b)
{
int re=;
for (;b;b>>=,a=1ll*a*a%mo) if (b&) re=1ll*re*a%mo;
return re;
}
void add(int u,int v)
{
edge[++tot]=(EDGE){v,head[u]};
head[u]=tot;
}
int tim;
int fa[N][],st[N],ed[N],dep[N],tid[N];
void dfs(int x,int p)
{
dep[x]=dep[p]+;
st[x]=++tim;tid[tim]=x;
fa[x][]=p;
for (int i=;i<=;i++) fa[x][i]=fa[fa[x][i-]][i-];
for (int i=head[x];i;i=edge[i].nxt)
{
int y=edge[i].to;
if (y==p) continue;
dfs(y,x);
}
ed[x]=tim;
}
int lca(int x,int y)
{
if (dep[x]<dep[y]) swap(x,y);
for (int i=;i>=;i--) if (dep[fa[x][i]]>=dep[y]) x=fa[x][i];
if (x==y) return x;
for (int i=;i>=;i--) if (fa[x][i]!=fa[y][i]) x=fa[x][i],y=fa[y][i];
return fa[x][];
}
bool cmp(const int &a,const int &b) {return dep[a]<dep[b];}
int idx;
int get(int x)
{
if (!hsh[x]) hsh[x]=++idx;
return hsh[x];
}
int sz;
int rt[N],mul[N*],ls[N*],rs[N*];
void ins(int &o,int lst,int l,int r,int x,int y)
{
o=++sz;
mul[o]=1ll*mul[lst]*y%mo;
ls[o]=ls[lst];rs[o]=rs[lst];
if (l==r) return;
int mid=l+r>>;
if (x<=mid) ins(ls[o],ls[lst],l,mid,x,y);
else ins(rs[o],rs[lst],mid+,r,x,y);
}
int query(int o,int l,int r,int x,int y)
{
if (l>=x&&r<=y) return mul[o];
int mid=l+r>>,re=;
if (x<=mid) re=1ll*re*query(ls[o],l,mid,x,y)%mo;
if (y>mid) re=1ll*re*query(rs[o],mid+,r,x,y)%mo;
return re;
}
int b[N];
int main()
{
freopen("half.in","r",stdin);
freopen("half.out","w",stdout);
pre();
int k=read();n=read();
for (int i=;i<=n;i++) a[i]=read(),b[i]=i;
for (int i=;i<n;i++)
{
int u=read(),v=read();
add(u,v);add(v,u);
}
dfs(,);
mul[]=;
sort(b+,b++n,cmp);
set<int>::iterator it1,it2,it3;
for (int i=;i<=n;i++)
{
int u=b[i],d=dep[u],tmp=a[u];
rt[d]=rt[dep[b[i-]]];
while (tmp>)
{
int t=mn[tmp],it=qpow(t,mo-),z=;
while (tmp%t==)
{
tmp/=t;
z*=t;
int y=get(z);
s[y].insert(st[u]);
it2=s[y].lower_bound(st[u]);
it1=it2;
if (it1!=s[y].begin()) --it1;
it3=it2;
++it3;
ins(rt[d],rt[d],,n,st[u],t);
int u1=,u2=;
if (it2!=s[y].begin())
{
u1=tid[*it1];int L=lca(u1,u);
ins(rt[d],rt[d],,n,st[L],it);
}
if (it3!=s[y].end())
{
u2=tid[*it3];int L=lca(u2,u);
ins(rt[d],rt[d],,n,st[L],it);
}
if (u1&&u2)
{
int L=lca(u1,u2);
ins(rt[d],rt[d],,n,st[L],t);
}
}
}
}
for (int i=dep[b[n]]+;i<=n;i++) rt[i]=rt[i-];
int q=read(),ans=;
while (q--)
{
int u=read()^(k*ans),d=min(n,dep[u]+read()^(k*ans));
printf("%d\n",query(rt[d],,n,st[u],ed[u]));
}
return ;
}

[jzoj 6086] [GDOI2019模拟2019.3.26] 动态半平面交 解题报告 (set+线段树)的更多相关文章

  1. [jzoj 6092] [GDOI2019模拟2019.3.30] 附耳而至 解题报告 (平面图转对偶图+最小割)

    题目链接: https://jzoj.net/senior/#main/show/6092 题目: 知识点--平面图转对偶图 在求最小割的时候,我们可以把平面图转为对偶图,用最短路来求最小割,这样会比 ...

  2. [jzoj 4528] [GDOI2019模拟2019.3.26] 要换换名字 (最大权闭合子图)

    题目链接: https://jzoj.net/senior/#contest/show/2683/0 题目: 题解: 不妨枚举一个点,让两颗树都以这个点为根,求联通块要么点数为$0$,要么包括根(即联 ...

  3. [jzoj 6087] [GDOI2019模拟2019.3.26] 获取名额 解题报告 (泰勒展开+RMQ+精度)

    题目链接: https://jzoj.net/senior/#main/show/6087 题目: 题解: 只需要统计$\prod_{i=l}^r (1-\frac{a_i}{x})$ =$exp(\ ...

  4. [JZOJ6075]【GDOI2019模拟2019.3.20】桥【DP】【线段树】

    Description N,M<=100000,S,T<=1e9 Solution 首先可以感受一下,我们把街道看成一行,那么只有给出的2n个点的纵坐标是有用的,于是我们可以将坐标离散化至 ...

  5. [jzoj 6093] [GDOI2019模拟2019.3.30] 星辰大海 解题报告 (半平面交)

    题目链接: https://jzoj.net/senior/#contest/show/2686/2 题目: 题解: 说实话这题调试差不多花了我十小时,不过总算借着这道题大概了解了计算几何的基础知识 ...

  6. [jzoj 6101] [GDOI2019模拟2019.4.2] Path 解题报告 (期望)

    题目链接: https://jzoj.net/senior/#main/show/6101 题目: 题解: 设$f_i$表示从节点$i$到节点$n$的期望时间,$f_n=0$ 最优策略就是如果从$i, ...

  7. [jzoj 6080] [GDOI2019模拟2019.3.23] IOer 解题报告 (数学构造)

    题目链接: https://jzoj.net/senior/#main/show/6080 题目: 题意: 给定$n,m,u,v$ 设$t_i=ui+v$ 求$\sum_{k_1+k_2+...+k_ ...

  8. [jzoj 6084] [GDOI2019模拟2019.3.25] 礼物 [luogu 4916] 魔力环 解题报告(莫比乌斯反演+生成函数)

    题目链接: https://jzoj.net/senior/#main/show/6084 https://www.luogu.org/problemnew/show/P4916 题目: 题解: 注: ...

  9. [JZOJ 5908] [NOIP2018模拟10.16] 开荒(kaihuang)解题报告 (树状数组+思维)

    题目链接: https://jzoj.net/senior/#contest/show/2529/1 题目: 题目背景:尊者神高达作为一个萌新,在升级路上死亡无数次后被一只大黄叽带回了师门.他加入师门 ...

随机推荐

  1. bzoj5216: [Lydsy2017省队十连测]公路建设

    题目思路挺巧妙的. 感觉应该可以数据结构一波,发现n很小可以搞搞事啊.然后又发现给了512mb,顿时萌生大力线段树记录的念头 一开始想的是记录节点的fa,然后发现搞不动啊?? 但其实边肯定最多只有n- ...

  2. DNS隧道工具汇总——补充,还有IP over DNS的工具NSTX、Iodine、DNSCat

    github上有一堆的工具:https://github.com/search?utf8=%E2%9C%93&q=DNS+tunnel+&type= DNS隧道大检阅 研究了一天的DN ...

  3. SAN (Storage Attached Network),即存储区域网络

    NAS和SAN既竞争又合作,很多高端NAS的后端存储就是SAN.NAS和SAN的整合也是存储设备的发展趋势,比如EMC的新产品VNX系列. 关于NAS和SAN的区别,可以列出很多来.比如带宽大小,距离 ...

  4. Java-MyBatis-杂项:MyBatis根据数组、集合查询

    ylbtech-Java-MyBatis-杂项:MyBatis根据数组.集合查询 1.返回顶部 1. foreach的主要用在构建in条件中,它可以在SQL语句中进行迭代一个集合.foreach元素的 ...

  5. 迭代Iterator的用法

    迭代→遍历: 一个标准化遍历各类容器里面的所有对象的方法类(典型的设计模式) 把访问逻辑从不同类型的集合类中抽象出来,从而避免向客户端暴露集合的内部结构 迭代(Iterator)与枚举(Enumera ...

  6. ROS-参数

    前言:参数的用法. 一.参数常用命令 命令 功能 rosparam list 参数列表 rosparam get 获取参数 rosparam set  设置参数 rosparam load 加载参数 ...

  7. iOS开发 小知识点

    1/ iOS汉字百分号互相转换. //汉字 NSString * name = @"时间终于将我对你的爱消耗殆尽"; //汉字转为百分比 NSString * encodeStri ...

  8. php基础-------preg_replace()与preg_replace_callback()

    1.preg_replace() 执行一个正则表达式的搜索和替换. 语法: mixed preg_replace ( mixed $pattern , mixed $replacement , mix ...

  9. ZBrush中Pinch捏挤笔刷介绍

    随着版本的升级ZBrush®中给我们提供了越来越多的笔刷,对于这款软件来说,笔刷的使用是第一要素,也会一直伴随我们创作.虽然Zbrush中有那么多的笔刷,但是很多朋友会根据自己的习惯来使用,这个并不是 ...

  10. nginx 过滤zip 类型的文件

    http://www.cnblogs.com/bass6/p/5500660.html