题目大意:给你一棵树,有两种操作,一个是修改某个点的权值,另一个是询问两点之间的距离以及路径上小于某个值的数的个数。

询问两点之间距离直接lca即可,对于求个数的问题可以用主席树完成。

 #include<bits/stdc++.h>
using namespace std;
inline int read(){
int s=;char ch=getchar();
for(;ch<''||ch>'';ch=getchar());
for(;ch>=''&&ch<='';ch=getchar())s=s*+ch-'';
return s;
}
int N,Q;
struct node{
int opt,x,y,c,t;
}q[];
int to[],next[],tot,h[];
int root[],ls[],rs[],size[];
int c[],rt,cnt;
int fa[][],dep[];
void add(int x,int y){
tot++;to[tot]=y;next[tot]=h[x];h[x]=tot;
}
void insert(int l,int r,int Ort,int Nrt,int x){
if(l==r){size[Nrt]=size[Ort]+;return;}
int mid=(l+r)>>;
if(x<=mid){
ls[Nrt]=++cnt;
rs[Nrt]=rs[Ort];
insert(l,mid,ls[Ort],ls[Nrt],x);
}else{
rs[Nrt]=++cnt;
ls[Nrt]=ls[Ort];
insert(mid+,r,rs[Ort],rs[Nrt],x);
}
size[Nrt]=size[ls[Nrt]]+size[rs[Nrt]];
}
void dfs(int x){
for(int i=;i<=;++i)
if(dep[x]<(<<i))break;
else fa[x][i]=fa[fa[x][i-]][i-];
for(int i=h[x];i;i=next[i]){
int v=to[i];
if(dep[v])continue;
dep[v]=dep[x]+;
fa[v][]=x;
if(c[v])insert(,Q,root[x],root[v]=++cnt,c[v]);
else root[v]=root[x];
dfs(v);
}
}
void init(){
N=read();
for(int i=;i<=N;++i){
int x=read();
if(x==)rt=i;
else add(x,i);
}
Q=read();
for(int i=;i<=Q;++i){
q[i].opt=read();
if(q[i].opt==)q[i].x=read(),q[i].y=read(),q[i].c=read();
else{
q[i].t=read();
if(!c[q[i].t])c[q[i].t]=i;
}
}
dep[rt]=;
if(c[rt])insert(,Q,root[],root[rt]=++cnt,c[rt]);
dfs(rt);
}
int lca(int x,int y){
if(dep[x]<dep[y])swap(x,y);
int d=dep[x]-dep[y];
for(int i=;i<=;++i)
if(d&(<<i))
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];
if(x==y)return x;
return fa[x][];
}
int ask(int l,int r,int rrt,int lrt,int x){
if(x<=)return ;
if(l==r)return size[rrt]-size[lrt];
int mid=(l+r)>>;
if(x<=mid)return ask(l,mid,ls[rrt],ls[lrt],x);
else return size[ls[rrt]]-size[ls[lrt]]+ask(mid+,r,rs[rrt],rs[lrt],x);
}
void work(){
for(int i=;i<=Q;++i){
if(q[i].opt==){
int k=lca(q[i].x,q[i].y);
int k1=dep[q[i].x]+dep[q[i].y]-*dep[k]+;
int k2=ask(,Q,root[q[i].x],root[fa[k][]],i-q[i].c-)+ask(,Q,root[q[i].y],root[k],i-q[i].c-);
printf("%d %d\n",k1,k2);
}
}
}
int main(){
init();
work();
return ;
}

最新文章

  1. tp框架之分页与第三方类的应用
  2. WEB安全:XSS漏洞与SQL注入漏洞介绍及解决方案
  3. SlickUpload 发布到IIS后报错
  4. Android中在sdcard上创建文件夹
  5. http协议之request
  6. Kylin上chromium不能用flash的解决命令
  7. eclipse插件svn 提交时报:&quot;svn is already locked&quot;解决方法
  8. android之handler obtainmessge与New message区别
  9. connectionStrings基本配置
  10. vue-cli webpack3扩展多模块打包
  11. 腾讯基于Kubernetes的企业级容器云平台GaiaStack (转)
  12. WebLogic: 内存溢出
  13. P3709 大爷的字符串题
  14. 在Ubuntu中增加root用户登录
  15. 极高效内存池实现 (cpu-cache)
  16. jquery轮播控件
  17. 【微信小程序】转载:微信小程序实战篇-下拉刷新与加载更多
  18. Python|花了一天,为大家整理的一套来自外国大佬的密码速查表
  19. 继承、super、this、抽象类
  20. 【Unity3D/C#】利用IEnumerable&lt;&gt;和yield产生斐波那契数列

热门文章

  1. AngularJS 学习之表格
  2. HTTP基础08--追加协议
  3. 浩瀚科技PDA移动开单|盘点机 数据采集器 条码扫描开单微POS软件 现场打印开单
  4. [工作bug]一个weblogic跨应用导致session丢失的bug之旅
  5. 17243 Huzi酱和他的俄罗斯套娃(贪心)
  6. HDU4609 3-idiots(母函数 + FFT)
  7. BZOJ4684 : Company Organization
  8. (转)linux命令行下的ftp 多文件下载和目录下载
  9. 修改文档框架:word-多级列表与标题样式相结合
  10. 你可能不再需要Underscore