CF226E Noble Knight's Path/bzoj4704 旅行
题目描述:
题解:
主席树维护大力树剖。
一条路径上不允许过的点的个数是当前袭击数-$y$时袭击数,
所以允许经过的点的个数是总数-当前袭击数+$y$时袭击数。
用主席树去维护每个时刻树链袭击数。
这样的话修改的时间复杂度是$O(nlogn)$的。
现在的问题是查询。
注意端点不算路径上的点,那么我们可以让起点和终点距离近一点。
然后有两种情况,起点先向上走/先向下走。
这两个都能用同样的暴跳二分解决。
上代码:
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
const int N = 100050;
const int M = 80*N;
template<typename T>
inline void read(T&x)
{
T f = 1,c = 0;char ch=getchar();
while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
while(ch>='0'&&ch<='9'){c=c*10+ch-'0';ch=getchar();}
x = f*c;
}
int n,m,hed[N],cnt,rot;
struct EG{int to,nxt;}e[N];
void ae(int f,int t)
{
e[++cnt].to = t;
e[cnt].nxt = hed[f];
hed[f] = cnt;
}
int dep[N],siz[N],top[N],fa[N],son[N],tin[N],tim,pla[N];
void dfs0(int u,int f)
{
fa[u] = f,siz[u] = 1,dep[u] = dep[f]+1;
for(int j=hed[u];j;j=e[j].nxt)
{
int to = e[j].to;
dfs0(to,u);siz[u]+=siz[to];
if(siz[to]>siz[son[u]])son[u]=to;
}
}
void dfs1(int u,int Top)
{
top[u] = Top,tin[u] = ++tim,pla[tim] = u;
if(son[u])dfs1(son[u],Top);
for(int j=hed[u];j;j=e[j].nxt)
{
int to = e[j].to;
if(to!=son[u])dfs1(to,to);
}
}
int get_lca(int x,int y)
{
while(top[x]!=top[y]){if(dep[top[x]]<dep[top[y]])swap(x,y);x=fa[top[x]];}
return dep[x]<dep[y]?x:y;
}
int get_son(int x,int y)
{
while(top[x]!=top[y]){if(fa[top[x]]==y)return top[x];x=fa[top[x]];}
return pla[tin[y]+1];
}
int rt[N];
struct pertree
{
int tot,ls[M],rs[M],siz[M];
void insert(int l,int r,int&u,int las,int qx)
{
u = ++tot;
ls[u] = ls[las],rs[u] = rs[las],siz[u] = siz[las]+1;
if(l==r)return ;
int mid = (l+r)>>1;
if(qx<=mid)insert(l,mid,ls[u],ls[las],qx);
else insert(mid+1,r,rs[u],rs[las],qx);
}
int query(int l,int r,int L,int R,int ql,int qr)
{
if(!L&&!R)return 0;
if(l==ql&&r==qr)return siz[R]-siz[L];
int mid = (l+r)>>1;
if(qr<=mid)return query(l,mid,ls[L],ls[R],ql,qr);
else if(ql>mid)return query(mid+1,r,rs[L],rs[R],ql,qr);
else return query(l,mid,ls[L],ls[R],ql,mid)+query(mid+1,r,rs[L],rs[R],mid+1,qr);
}
}tr;
int query(int x,int y,int las,int now)
{
int ret = 0;
while(top[x]!=top[y])
{
ret+=dep[x]-dep[top[x]]+1-tr.query(1,n,rt[las],rt[now],tin[top[x]],tin[x]);
x = fa[top[x]];
}
return ret+dep[x]-dep[y]+1-tr.query(1,n,rt[las],rt[now],tin[y],tin[x]);
}
int dv(int l,int r,int las,int now,int k)
{
int ret = l-1;int tmp = r;
while(l<=r)
{
int mid = (l+r)>>1;
if(tmp-mid+1-tr.query(1,n,rt[las],rt[now],mid,tmp)>=k)ret=mid,l=mid+1;
else r=mid-1;
}
return pla[ret];
}
int jmp(int x,int y,int las,int now,int k)
{
while(top[x]!=top[y])
{
int tmp = dep[x]-dep[top[x]]+1-tr.query(1,n,rt[las],rt[now],tin[top[x]],tin[x]);
if(k>tmp)k-=tmp,x=fa[top[x]];
else return dv(tin[top[x]],tin[x],las,now,k);
}
return dv(tin[y],tin[x],las,now,k);
}
int main()
{
// freopen("tt.in","r",stdin);
read(n);
for(int f,i=1;i<=n;i++)
{
read(f);
if(!f)rot=i;
else ae(f,i);
}
dfs0(rot,0),dfs1(rot,rot);
read(m);
for(int op,a,b,c,k,y,i=1;i<=m;i++)
{
read(op);
if(op==1)
{
read(c);
tr.insert(1,n,rt[i],rt[i-1],tin[c]);
}else
{
rt[i]=rt[i-1];
read(a),read(b),read(k),read(y);
if(fa[a]==b||fa[b]==a){puts("-1");continue;}
int Lca = get_lca(a,b);
if(a!=Lca&&b!=Lca)a=fa[a],b=fa[b];
else if(a==Lca)b=fa[b],a=get_son(b,a);
else a=fa[a],b=get_son(a,b);
Lca = get_lca(a,b);
if(a==Lca)
{
int sum = query(b,a,y,i);
if(sum<k){puts("-1");continue;}
printf("%d\n",jmp(b,a,y,i,sum-k+1));
}else
{
int alc = get_son(a,Lca);
int sum = query(a,alc,y,i);
if(sum>=k){printf("%d\n",jmp(a,alc,y,i,k));continue;}
k-=sum;
sum = query(b,Lca,y,i);
if(sum<k){puts("-1");continue;}
printf("%d\n",jmp(b,Lca,y,i,sum-k+1));
}
}
}
return 0;
}
CF226E Noble Knight's Path/bzoj4704 旅行的更多相关文章
- [CF226E]Noble Knight's Path
[CF226E]Noble Knight's Path 题目大意: 一棵\(n(n\le10^5)\)个结点的树,初始时所有结点都是白色.\(m(m\le10^5)\)次操作,操作包含以下两种: 将点 ...
- [Codeforces 226E]Noble Knight's Path
题目大意:有一棵n个节点的树,m年.初始每个节点都有.每天有如下操作:1. 给定c,让c没有(c只可能没有一次).2. 给定s,t,k,y,求从第y+1年到现在(即忽略y+1年之前的操作1),s到t的 ...
- Lintcode: Knight Shortest Path
Given a knight in a chessboard (a binary matrix with 0 as empty and 1 as barrier) with a source posi ...
- The Sorrows of Young Werther
The Sorrows of Young Werther J.W. von Goethe Thomas Carlyle and R.D. Boylan Edited by Nathen Haskell ...
- 九章lintcode作业题
1 - 从strStr谈面试技巧与代码风格 必做题: 13.字符串查找 要求:如题 思路:(自写AC)双重循环,内循环读完则成功 还可以用Rabin,KMP算法等 public int strStr( ...
- 宽度优先搜索(BFS)— 20180909 - 20180917
BFS几类题: 1.图的遍历:a.层级遍历 b.由点及面 c.拓扑排序 2.简单图最短路径: 简单图:1.无向图 2.边权重一致 图的时间复杂度: N个点,M条边,M最大是N^2,时间复杂度O(N+M ...
- BFS算法的优化 双向宽度优先搜索
双向宽度优先搜索 (Bidirectional BFS) 算法适用于如下的场景: 无向图 所有边的长度都为 1 或者长度都一样 同时给出了起点和终点 以上 3 个条件都满足的时候,可以使用双向宽度优先 ...
- A Child's History of England.22
CHAPTER 8 ENGLAND UNDER WILLIAM THE FIRST, THE NORMAN CONQUEROR Upon the ground where the brave Haro ...
- 【BZOJ4704】旅行 树链剖分+可持久化线段树
[BZOJ4704]旅行 Description 在Berland,有n个城堡.每个城堡恰好属于一个领主.不同的城堡属于不同的领主.在所有领主中有一个是国王,其他的每个领主都直接隶属于另一位领主,并且 ...
随机推荐
- 08python语法入门--基本数据类型及内置方法
数字类型int与float 定义 类型转换 使用 字符串 定义 类型转换 使用 优先掌握的操作 需要掌握的操作 了解操作 列表 定义 类型转化 使用 优先掌握的操作 需要掌握的操作 了解操作 元组 作 ...
- 操作系统发展史 & 进程
今日内容 UDP协议 操作系统发展史 进程 单核情况下的进程调度 进程三状态图 同步异步 阻塞非阻塞 内容详细 一.UDP协议 1.什么是UDP协议 UDP是传输层的协议,功能即为在IP的数据报服务之 ...
- Solution -「洛谷 P5236」「模板」静态仙人掌
\(\mathcal{Description}\) Link. 给定一个 \(n\) 个点 \(m\) 条边的仙人掌,\(q\) 组询问两点最短路. \(n,q\le10^4\),\(m\ ...
- 深入MySQL(一):MySQL的组织架构
今天开始将自己所学过的MySQL的知识都尝试融会贯通,并且用写博客的方式记录分享下来. 今天讲的主题是MySQL的组织架构,对于学习一个中间件或者开源项目而言,我觉得最重要的便是先知晓其组织架构,以一 ...
- 一个接口多个实现Spring如何实现正确注入
阅读源码的时候,时不时脑子中冒出一个问题:如果自己写一个单例的容器,一个接口多个实现怎么正确地将每个实现都缓存容器中并准确地注入呢?阅读Dubbo源码时也有类似的问题冒出来. 对于@Autowire注 ...
- Kafka经典三大问:数据有序丢失重复
Kafka经典三大问:数据有序丢失重复 在kafka中有三个经典的问题: 如何保证数据有序性 如何解决数据丢失问题 如何处理数据重复消费 这些不光是面试常客,更是日常使用过程中会遇到的几个问题,下面分 ...
- 挖到一款免费好用的web报表插件
最近公司项目需要用到报表,公司领导要求我来调研下报表工具.开始的时候了解了目前市场上功能强大,占有率高的两款报表工具,帆软报表和润乾报表,这两款报表工具功能比较强大,覆盖的行业较广,基本能满足所有的报 ...
- LINUX服务器常用命令
转至:https://my.oschina.net/7shell/blog/70508 常用命令 查看所有80端口的连接数 1. netstat -nat|grep -i "80" ...
- python+pytest(3)-接口测试一般流程及方法
首先我们要明确,通常所接口测试其实就属于功能测试,主要校验接口是否实现预定的功能,虽然有些情况下可能还需要对接口进行性能测试.安全性测试. 在学习接口自动化测试之前,我们先来了解手工接口测试怎样进行. ...
- ABP 使用ElasticSearch、Kibana、Docker 进行日志收集
ABP 使用ElasticSearch.Kibana.Docker 进行日志收集 后续会根据公司使用的技术,进行技术整理分享,都是干货哦别忘了关注我!!! 最近领导想要我把项目日志进行一个统一收集,因 ...