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. Windows -- 从注册表删除IE浏览器加载项

    Windows -- 从注册表删除IE浏览器加载项 1.  一部分加载项从注册表以下位置直接删除 2.  一部分扩展项从注册表以下位置直接删除

  2. php redis 处理websocket聊天记录

    <?php ini_set('display_errors', 'on'); class chatClass { private $redis; //这个变量模拟用户当前状态,是否登录,是否可查 ...

  3. 重大变革即将来临 5G CPE会替代光纤入户吗?

    导读 从国内的新闻报道上我们可以看到,从2018年下半年开始各大重要活动.春晚直播等,都宣布已经使用5G网络.既然支持5G网络的终端都还没有正式上市,那么5G网络是如何使用的呢?答案是5G CPE设备 ...

  4. vpshere6 ESXI 禁止登陆 "执行此操作的权限被拒绝"

    vCenter在添加ESXI主机时,锁定模式选择“正常”,导致无法直接登陆ESXI宿主机,现象如下: 解决方法:

  5. java前端js和框架内容知识和面试

    关于数据库知识和面试 关于JAVA知识和面试 一.多个ajax请求执行顺序问题 若点击一个操作内,发送两个ajax请求,其中一个请求会不会等待另一个请求执行完毕之后再执行? 不会,这两个异步请求会同时 ...

  6. 免费高端出辕营,横空出世惊鬼神 Excel插件:ExcelPower_Helper 0.41初出茅庐

    免费高端出辕营,横空出世惊鬼神 Excel插件:ExcelPower_Helper 0.41初出茅庐        隐鹤 倾心开发 2019.4.1 1.   引言 经过前后大约零零散散的一年的开发, ...

  7. IDEA编译器的常用快捷键

    今天想简单分享一下IDEA编译器的常用快捷键 1. -----------自动代码-------- 常用的有fori/sout/psvm+Tab即可生成循环.System.out.main方法等boi ...

  8. QQ浏览器、火狐浏览器中页面有点大的问题记录

    做页面时候,发现火狐和腾讯QQ浏览器有个问题,就是会将页面显示的比较大,像点了缩放比例120%似的,事实上缩放比例是100%,很奇怪. 甚至面对这个问题,连腾讯公司主页也会放大,也让我很困惑. 比如: ...

  9. c提高第五次作业

    重写结构体嵌套一级指针老师和二级指针学生的代码 //结构体类型,每个导师有三个学生 typedef struct Teacher { char *tName; //导师 char **stu; //三 ...

  10. tensorflow-TensorBoard

    Tensorborad--> 是Tensorflow的可视化工具,它可以通过Tensorflow程序运行过程中输出的日志文件可视化Tensorflow程序的运行状态.Tensorflow和Ten ...