题解

对于这个 \(abs\) 就是求大于 \(r\) 的最小值,小于 \(r\) 的最大值,建权值线段树或平衡树。

因为是 \(k\) 个点的联通块,就是求它们的 \(lca\) 到它们的链,可持久化线段树就行

在这里,只需要儿子继承父亲即可,因为要求一条链。

在搜前趋时,右儿子有就搜右儿子,搜出一个答案后就停止,这样可以做到每次最多搜 \(log\) 个区间,只有一个区间会继续向下搜,所以总的也是 \(log\)

总复杂度 \(\mathcal O\rm (klogn)\)

Code
#include<bits/stdc++.h>
#define ri register signed
#define p(i) ++i
using namespace std;
namespace IO{
char buf[1<<21],*p1=buf,*p2=buf;
#define gc() p1==p2&&(p2=(p1=buf)+fread(buf,1,1<<21,stdin),p1==p2)?EOF:*p1++
template<typename T>inline void read(T &x) {
ri f=1;x=0;register char ch=gc();
while(ch<'0'||ch>'9') {if (ch=='-') f=0;ch=gc();}
while(ch>='0'&&ch<='9') {x=(x<<1)+(x<<3)+(ch^48);ch=gc();}
x=f?x:-x;
}
}
using IO::read;
namespace nanfeng{
#define FI FILE *IN
#define FO FILE *OUT
template<typename T>inline T cmax(T x,T y) {return x>y?x:y;}
template<typename T>inline T cmin(T x,T y) {return x>y?y:x;}
static const int N=1e5+7;
int first[N],st[N<<1][19],lg[N<<1],head[N],f[N],dep[N],a[N],p[N],lca,ol,t=1,typ,n,q,fg,mx,ans,lst;
struct edge{int v,nxt;}e[N<<1];
inline void add(int u,int v) {
e[t].v=v,e[t].nxt=first[u],first[u]=t++;
e[t].v=u,e[t].nxt=first[v],first[v]=t++;
}
void dfs_init(int x,int fa) {
f[x]=fa;
head[st[p(ol)][0]=x]=ol;
for (ri i(first[x]),v;i;i=e[i].nxt) {
if ((v=e[i].v)==fa) continue;
dep[v]=dep[x]+1;
dfs_init(v,x);
st[p(ol)][0]=x;
}
}
inline void init_rmq() {
dfs_init(1,0);
for (ri i(2);i<=ol;p(i)) lg[i]=lg[i>>1]+1;
ri k=lg[ol];
for (ri j(1);j<=k;p(j)) {
ri len=1<<j;
for (ri i(1);i+len-1<=ol;p(i)) {
ri x1=st[i][j-1],x2=st[i+(1<<j-1)][j-1];
st[i][j]=dep[x1]<dep[x2]?x1:x2;
}
}
}
inline int Getlca(int u,int v) {
if (head[u]>head[v]) swap(u,v);
int k=lg[head[v]-head[u]+1];
ri x1=st[head[u]][k],x2=st[head[v]-(1<<k)+1][k];
return dep[x1]<dep[x2]?x1:x2;
}
struct Seg{
#define ls(x) T[x].l
#define rs(x) T[x].r
#define up(x) T[x].nm=T[ls(x)].nm+T[rs(x)].nm
struct segmenttree{int l,r,nm;}T[N<<5];
int rt[N],tot;
void update(int &x,int p,int l,int r) {
if (!x) x=p(tot);
if (l==r) return (void)(p(T[x].nm));
int mid(l+r>>1);
if (p<=mid) update(ls(x),p,l,mid);
else update(rs(x),p,mid+1,r);
up(x);
}
int merge(int x,int y) {
if (!x||!y) return (x|y);
T[x].nm+=T[y].nm;
ls(x)=merge(ls(x),ls(y));
rs(x)=merge(rs(x),rs(y));
return x;
}
int calcx(int x,int pre,int l,int r) {
if (l==r) return l;
int mid(l+r>>1);
if (T[rs(x)].nm-T[rs(pre)].nm) return calcx(rs(x),rs(pre),mid+1,r);
return calcx(ls(x),ls(pre),l,mid);
}
int calcn(int x,int pre,int l,int r) {
if (l==r) return l;
int mid(l+r>>1);
if (T[ls(x)].nm-T[ls(pre)].nm) return calcn(ls(x),ls(pre),l,mid);
return calcn(rs(x),rs(pre),mid+1,r);
}
int queryx(int x,int pre,int l,int r,int lt,int rt) {
if (!x) return -1;
if (!(T[x].nm-T[pre].nm)) return -1;
if (l<=lt&&rt<=r) return calcx(x,pre,lt,rt);
int mid(lt+rt>>1),res(-1);
if (r>mid&&T[rs(x)].nm-T[rs(pre)].nm) res=queryx(rs(x),rs(pre),l,r,mid+1,rt);
if (res!=-1) return res;
if (l<=mid&&T[ls(x)].nm-T[ls(pre)].nm) res=queryx(ls(x),ls(pre),l,r,lt,mid);
return res;
}
int queryn(int x,int pre,int l,int r,int lt,int rt) {
if (!x) return -1;
if (!(T[x].nm-T[pre].nm)) return -1;
if (l<=lt&&rt<=r) return calcn(x,pre,lt,rt);
int mid(lt+rt>>1),res(-1);
if (l<=mid&&T[ls(x)].nm-T[ls(pre)].nm) res=queryn(ls(x),ls(pre),l,r,lt,mid);
if (res!=-1) return res;
if (r>mid&&T[rs(x)].nm-T[rs(pre)].nm) res=queryn(rs(x),rs(pre),l,r,mid+1,rt);
return res;
}
}T;
void dfs(int x) {
T.update(T.rt[x],a[x],1,mx);
if (f[x]) T.merge(T.rt[x],T.rt[f[x]]);
for (ri i(first[x]),v;i;i=e[i].nxt) {
if ((v=e[i].v)==f[x]) continue;
dfs(v);
}
}
inline int main() {
// FI=freopen("nanfeng.in","r",stdin);
// FO=freopen("nanfeng.out","w",stdout);
read(n),read(q),read(typ);
for (ri i(1);i<=n;p(i)) read(a[i]),mx=cmax(mx,a[i]);
for (ri i(1),u,v;i<n;p(i)) read(u),read(v),add(u,v);
init_rmq();
dfs(1);
for (ri i(1),r,k;i<=q;p(i)) {
read(r),read(k);
ans=INT_MAX;
for (ri j(1);j<=k;p(j)) read(p[j]),p[j]=(p[j]-1+lst*typ)%n+1;
lca=p[1];
for (ri j(2);j<=k;p(j)) lca=Getlca(p[j],lca);
for (ri j(1);j<=k;p(j)) {
fg=0;
ri a1=T.queryx(T.rt[p[j]],T.rt[f[lca]],1,r,1,mx),a2=-1;
if (r<=mx) a2=T.queryn(T.rt[p[j]],T.rt[f[lca]],r,mx,1,mx);
if (a1!=-1) ans=cmin(ans,abs(a1-r));
if (a2!=-1) ans=cmin(ans,abs(a2-r));
}
printf("%d\n",lst=ans);
}
return 0;
}
}
int main() {return nanfeng::main();}

NOIP 模拟 $22\; \rm e$的更多相关文章

  1. NOIP 模拟 $22\; \rm f$

    题解 \(by\;zj\varphi\) 对于一个数,如果它二进制下第 \(i\) 位为 \(1\),那么 \(\rm x\) 在这一位选 \(1\) 的贡献就是和它不同的最高为为 \(i\) 的数的 ...

  2. NOIP 模拟 $22\; \rm d$

    题解 很好的贪心题 考虑去掉的矩形一定是几个 \(a\) 最小的,几个 \(b\) 最小的,枚举去掉几个 \(a\),剩下的去掉 \(b\) 先对 \(a\) 排序,用小根堆维护 \(b\) ,记录哪 ...

  3. noip模拟22[d·e·f]

    noip模拟22 solutions 哈哈哈,这次暴力打满直接190,其实不到哈哈哈,187.. 这次的题暴力极其好打,但是正解确实不简单... 打了好久才改完这个题,改完的时候爽暴了 这些一个字母的 ...

  4. 2021.5.22 noip模拟1

    这场考试考得很烂 连暴力都没打好 只拿了25分,,,,,,,,好好总结 T1序列 A. 序列 题目描述 HZ每周一都要举行升旗仪式,国旗班会站成一整列整齐的向前行进. 郭神作为摄像师想要选取其中一段照 ...

  5. 5.22考试总结(NOIP模拟1)

    5.22考试总结(NOIP模拟1) 改题记录 T1 序列 题解 暴力思路很好想,分数也很好想\(QAQ\) (反正我只拿了5pts) 正解的话: 先用欧拉筛把1-n的素数筛出来 void get_Pr ...

  6. 7.22 NOIP模拟7

    又是炸掉的一次考试 T1.方程的解 本次考试最容易骗分的一道题,但是由于T2花的时间太多,我竟然连a+b=c都没判..暴力掉了40分. 首先a+b=c,只有一组解. 然后是a=1,b=1,答案是c-1 ...

  7. NOIP模拟 1

    NOIP模拟1,到现在时间已经比较长了.. 那天是6.14,今天7.18了 //然鹅我看着最前边缺失的模拟1,还是终于忍不住把它补上,为了保持顺序2345重新发布了一遍.. #   用  户  名   ...

  8. NOIP 模拟 $20\; \rm y$

    题解 \(by\;zj\varphi\) 首先发现一共最多只有 \(2^d\) 种道路,那么可以状压,(不要 \(dfs\),会搜索过多无用的状态) 那么设 \(f_{i,j,k}\) 为走 \(i\ ...

  9. NOIP模拟3

    期望得分:30+90+100=220 实际得分:30+0+10=40 T1智障错误:n*m是n行m列,硬是做成了m行n列 T2智障错误:读入三个数写了两个%d T3智障错误:数值相同不代表是同一个数 ...

随机推荐

  1. 《PHP设计模式大全》系列分享专栏

    <PHP设计模式大全>已整理成PDF文档,点击可直接下载至本地查阅https://www.webfalse.com/read/201739.html 文章 php设计模式介绍之编程惯用法第 ...

  2. ZooKeeper 分布式锁 Curator 源码 01:可重入锁

    前言 一般工作中常用的分布式锁,就是基于 Redis 和 ZooKeeper,前面已经介绍完了 Redisson 锁相关的源码,下面一起看看基于 ZooKeeper 的锁.也就是 Curator 这个 ...

  3. Linux | 压缩与解压详解

    tar tar 命令用于对文件进行打包压缩或解压,格式: tar [选项][文件] tar命令的参数及其作用 参数 作用 -c 创建压缩文件 -x 解开压缩文件 -t 查看压缩包内有哪些文件 -z 用 ...

  4. webdriver xpath

    aa=wd.find_elements_by_xpath('//a') for a in aa: print(a.text) #显示所有A标签中文本 aa=wd.find_elements_by_xp ...

  5. Requests方法 -- post

    >>> import requests  导入requests库 >>> help(requests)  #查看requests方法Help on package ...

  6. 手把手教你用java实现二分查找树及其相关操作

    二分查找树(Binary Search Tree)的基本操作有搜索.求最大值.求最小值.求前继.求后继.插入及删除. 对二分查找树的进行基本操作所花费的时间与树的高度成比例.例如有n个节点的完全二叉树 ...

  7. windows系统下 PHP怎么安装redis扩展

    在windows系统下安装redis就不赘述了,基本上就是下一步,下一步. 然后通过通过命令行启动服务. 我是在xamp 3.2.2的集成环境下进行本地redis扩展安装配置的,php的版本是5.6. ...

  8. ajax原理及应用(十六)

    前言 AJAX即"Asynchronous Javascript And XML",是指一种创建交互式网页应用的网页开发技术.AJAX 是一种用于创建快速动态网页的技术.它可以令开 ...

  9. odoo12里面的RPC【远程过程调用】

    odoo的RPC有两种:RPC API:1.xml-rpc                                                      2.json-rpc 案例   x ...

  10. Pb代理工具之mitmproxy

    mitmproxy 一 . mitmproxy介绍 mitmproxy 就是用于 MITM 的 proxy,MITM 即中间人攻击(Man-in-the-middle attack). 不同于 fid ...