Description

In the NN country, there are n cities, numbered from 1 to n, and n−1 roads, connecting them. There is a roads path between any two cities.

There are m bidirectional bus routes between cities. Buses drive between two cities taking the shortest path with stops in every city they drive through. Travelling by bus, you can travel from any stop on the route to any other. You can travel between cities only by bus.

You are interested in q questions: is it possible to get from one city to another and what is the minimum number of buses you need to use for it?

Input

The first line contains a single integer n (2≤n≤2⋅105) — the number of cities.

The second line contains n−1 integers p2,p3,…,pn (1≤pi<i), where pi means that cities pi and i are connected by road.

The third line contains a single integer m (1≤m≤2⋅105) — the number of bus routes.

Each of the next m m lines contains 2 integers a and b (1≤a,b≤n, a≠b), meaning that there is a bus route between cities a and b. It is possible that there is more than one route between two cities.

The next line contains a single integer q (1≤q≤2⋅105) — the number of questions you are interested in.

Output

Print the answer for each question on a separate line. If there is no way to get from one city to another, print −1. Otherwise print the minimum number of buses you have to use.

题意:给定一棵 $n$ 个点的树, $m$ 条链, $q$ 个询问,每次询问 $a$ 到 $b$ 之间的路径最少可用几条给定链完全覆盖,无解输出 $-1$ 。

分析:

对于每一条 $a$ 与$b$ 间的路径,都可拆分为 $a$ 到 $lca$ 的路径和 $b$ 到 $lca$ 的路径

采用贪心策略, $low[x][i]$ 表示从 $x$ 点出发向上选择不超过 $2^i$ 条链可抵达的深度最浅的点。这时对于每一个询问可将询问的两个端点修改为利用贪心策略跳到的深度大于 $lca$ 且深度最小的节点,并记录下答案,这个过程可以用倍增完成。注意特判端点即 $lca$ 的情况。

然后出现两种情况。若修改后的两个端点出现在同一条给定链上,答案为原答案 $+1$ ,否则答案为原答案 $+2$ 。问题模型转换为,每次询问一个点对是否出现在同一条给定链上。记录下 $dfs$ 序,在深搜过程中利用树状数组统计即可。

时间复杂度 $O(nlogn)$ 。

 #include<cstdio>
#include<cstring>
#include<algorithm>
#include<vector>
#define LL long long
using namespace std;
const int N=2e5+;
const int inf=0x3f3f3f3f;
int n,m,Q,cnt,val,x,y,ind;
int deep[N],in[N],out[N],last[N];
int first[N],ans[N],tr[N];
int fa[N][],low[N][];
bool ok[N];
vector<int> a[N],b[N];
struct edge{int to,next;}e[N];
struct chain{int x,y,t;}c[N],q[N];
int read()
{
int x=,f=;char c=getchar();
while(c<''||c>''){if(c=='-')f=-;c=getchar();}
while(c>=''&&c<=''){x=x*+c-'';c=getchar();}
return x*f;
}
void ins(int u,int v){e[++cnt]=(edge){v,first[u]};first[u]=cnt;}
void dfs(int x)
{
in[x]=++ind;
for(int i=;(<<i)<=deep[x];i++)
fa[x][i]=fa[fa[x][i-]][i-];
for(int i=first[x];i;i=e[i].next)
{
deep[e[i].to]=deep[x]+;
dfs(e[i].to);
}
out[x]=ind;
}
int lca(int x,int y)
{
if(deep[x]<deep[y])swap(x,y);
int d=deep[x]-deep[y];
for(int i=;(<<i)<=d;i++)
if((<<i)&d)x=fa[x][i];
if(x==y)return x;
for(int i=;i>=;i--)
if((<<i)<=deep[x]&&fa[x][i]!=fa[y][i])
x=fa[x][i],y=fa[y][i];
return fa[x][];
}
void dfslow(int x)
{
for(int i=first[x];i;i=e[i].next)
{
int to=e[i].to;dfslow(to);
if(deep[low[to][]]<deep[low[x][]])
low[x][]=low[to][];
}
}
int find(int x,int t)
{
if(deep[low[x][]]>deep[t]){val=-inf;return -;}
if(x==t){val=-;return ;}
val=;
for(int i=;i>=;i--)
if(deep[low[x][i]]>deep[t])
x=low[x][i],val|=(<<i);
return x;
}
int lowbit(int x){return x&(-x);}
void add(int x,int v){for(;x<=n;x+=lowbit(x))tr[x]+=v;}
int query(int x){int ans=;for(;x;x-=lowbit(x))ans+=tr[x];return ans;}
void work(int x)
{
for(int sz=b[x].size(),i=;i<sz;i++)
{
int t=b[x][i];
last[t]=query(out[q[t].y])-query(in[q[t].y]-);
}
for(int sz=a[x].size(),i=;i<sz;i++)add(in[a[x][i]],);
for(int i=first[x];i;i=e[i].next)work(e[i].to);
for(int sz=b[x].size(),i=;i<sz;i++)
{
int t=b[x][i];
if(query(out[q[t].y])-query(in[q[t].y]-)!=last[t])ok[t]=true;
}
}
int main()
{
n=read();
for(int i=;i<=n;i++)
fa[i][]=read(),ins(fa[i][],i);
dfs();
for(int i=;i<=n;i++)low[i][]=i;
m=read();
for(int i=;i<=m;i++)
{
c[i].x=read();c[i].y=read();
c[i].t=lca(c[i].x,c[i].y);
if(deep[c[i].t]<deep[low[c[i].x][]])
low[c[i].x][]=c[i].t;
if(deep[c[i].t]<deep[low[c[i].y][]])
low[c[i].y][]=c[i].t;
a[c[i].x].push_back(c[i].y);
a[c[i].y].push_back(c[i].x);
}
dfslow();
for(int t=;t<=n;t++)
for(int i=;i<=;i++)
low[t][i]=low[low[t][i-]][i-];
Q=read();
for(int i=;i<=Q;i++)
{
q[i].x=read();q[i].y=read();
q[i].t=lca(q[i].x,q[i].y);
ans[i]=;
x=find(q[i].x,q[i].t);ans[i]+=val;
y=find(q[i].y,q[i].t);ans[i]+=val;
if(x>&&y>)
{
q[i].x=x;q[i].y=y;
b[x].push_back(i);
}
}
work();
for(int i=;i<=Q;i++)
if(ok[i])ans[i]--;
for(int i=;i<=Q;i++)
printf("%d\n",ans[i]<?-:ans[i]);
return ;
}

【codeforces 983E】NN country的更多相关文章

  1. 【codeforces 415D】Mashmokh and ACM(普通dp)

    [codeforces 415D]Mashmokh and ACM 题意:美丽数列定义:对于数列中的每一个i都满足:arr[i+1]%arr[i]==0 输入n,k(1<=n,k<=200 ...

  2. 【codeforces 370C】Mittens

    [题目链接]:http://codeforces.com/problemset/problem/370/C [题意] 给你n个人,每个人都有一双相同颜色的手套; 然允许在所有人之间交换手套; (每个人 ...

  3. 【42.07%】【codeforces 558A】Lala Land and Apple Trees

    time limit per test1 second memory limit per test256 megabytes inputstandard input outputstandard ou ...

  4. 【codeforces 546E】Soldier and Traveling

    time limit per test1 second memory limit per test256 megabytes inputstandard input outputstandard ou ...

  5. 【codeforces 752F】Santa Clauses and a Soccer Championship

    time limit per test2 seconds memory limit per test256 megabytes inputstandard input outputstandard o ...

  6. 【27.66%】【codeforces 592D】Super M

    time limit per test2 seconds memory limit per test256 megabytes inputstandard input outputstandard o ...

  7. 【codeforces 761B】Dasha and friends

    time limit per test2 seconds memory limit per test256 megabytes inputstandard input outputstandard o ...

  8. 【codeforces 762B】USB vs. PS/2

    time limit per test2 seconds memory limit per test256 megabytes inputstandard input outputstandard o ...

  9. 【codeforces div3】【E. Cyclic Components】

    E. Cyclic Components time limit per test 2 seconds memory limit per test 256 megabytes input standar ...

随机推荐

  1. AngularJS学习之旅—AngularJS 事件(十四)

    1.AngularJS 事件 ng-click ( 适用标签 :所有,触发事件:单击): ng-dblclick( 适用标签 :所有,触发事件:双击): ng-blur(适用标签 : a,input, ...

  2. Git 简单粗暴使用

    1.现在总结一下今天学的两点内容: 初始化一个Git仓库,使用git init命令. 添加文件到Git仓库,分两步: 第一步,使用命令git add <file>,注意,可反复多次使用,添 ...

  3. 【推荐】Pencil原型设计工具

    官网:http://pencil.evolus.vn/ 试用了一下,确实感觉很好用,整体体验上是一种“舒畅”的感觉,真心点赞推荐.整体功能上没有任何多余的东西,让人感觉上手就能用.虽然个人英语水平不咋 ...

  4. 网络流之最小费用最大流 P1251 餐巾计划问题

    题目描述 一个餐厅在相继的 NN 天里,每天需用的餐巾数不尽相同.假设第 ii 天需要 r_iri​块餐巾( i=1,2,...,N).餐厅可以购买新的餐巾,每块餐巾的费用为 pp 分;或者把旧餐巾送 ...

  5. R语言学习——数据合并及绘制密度分布曲线图

    setwd("E:/08_cooperation/07_X-lab/06-Crosstalk/Aadapter_primer")# 读取lane01.txt,并对其按列进行相加处理 ...

  6. slice 与 splice 的区别

    slice: 定义一个数组:let b = ['a','b','c','d','e'] b:["a", "b", "c", "d& ...

  7. Command "python setup.py egg_info" failed with error code 1 in C:\Users\w5659\AppData\Local\Temp\pip-install-t7uomu4r\xa dmin\

    Error msg: C:\Users\w5659>pip install xadmin Collecting xadmin Using cached https://files.pythonh ...

  8. centos下安装Vmware-tools时出现的问题

    今天装了centos,想共享一个文件,需要安装Vmware-tools. 正常的步骤: 安装Vmware-tools 1.挂载VMwareTools光驱.虚拟机选项栏中选[虚拟机]-->[安装v ...

  9. JS操作iframe元素

    1.  demo1.html页面中有个iframe元素,iframe元素的src是iframe1.html,怎么在demo1.html页面中操作iframe1.html页面 答曰:demo1.html ...

  10. springboot实现简单的文件上传

    承接上一篇,这里记录一下简单的springboot文件上传的方式 首先,springboot简单文件上传不需要添加额外的jar包和配置 这里贴一下后端controller层的实现代码 补一份前台的HT ...