BZOJ4448:[SCO2015]情报传递
2024-08-21 00:16:21
题目大意:给你一棵树,有两种操作,一个是修改某个点的权值,另一个是询问两点之间的距离以及路径上小于某个值的数的个数。
询问两点之间距离直接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 ;
}
最新文章
- tp框架之分页与第三方类的应用
- WEB安全:XSS漏洞与SQL注入漏洞介绍及解决方案
- SlickUpload 发布到IIS后报错
- Android中在sdcard上创建文件夹
- http协议之request
- Kylin上chromium不能用flash的解决命令
- eclipse插件svn 提交时报:";svn is already locked";解决方法
- android之handler obtainmessge与New message区别
- connectionStrings基本配置
- vue-cli webpack3扩展多模块打包
- 腾讯基于Kubernetes的企业级容器云平台GaiaStack (转)
- WebLogic: 内存溢出
- P3709 大爷的字符串题
- 在Ubuntu中增加root用户登录
- 极高效内存池实现 (cpu-cache)
- jquery轮播控件
- 【微信小程序】转载:微信小程序实战篇-下拉刷新与加载更多
- Python|花了一天,为大家整理的一套来自外国大佬的密码速查表
- 继承、super、this、抽象类
- 【Unity3D/C#】利用IEnumerable<;>;和yield产生斐波那契数列
热门文章
- AngularJS 学习之表格
- HTTP基础08--追加协议
- 浩瀚科技PDA移动开单|盘点机 数据采集器 条码扫描开单微POS软件 现场打印开单
- [工作bug]一个weblogic跨应用导致session丢失的bug之旅
- 17243 Huzi酱和他的俄罗斯套娃(贪心)
- HDU4609 3-idiots(母函数 + FFT)
- BZOJ4684 : Company Organization
- (转)linux命令行下的ftp 多文件下载和目录下载
- 修改文档框架:word-多级列表与标题样式相结合
- 你可能不再需要Underscore