【codeforces 983E】NN country
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的更多相关文章
- 【codeforces 415D】Mashmokh and ACM(普通dp)
[codeforces 415D]Mashmokh and ACM 题意:美丽数列定义:对于数列中的每一个i都满足:arr[i+1]%arr[i]==0 输入n,k(1<=n,k<=200 ...
- 【codeforces 370C】Mittens
[题目链接]:http://codeforces.com/problemset/problem/370/C [题意] 给你n个人,每个人都有一双相同颜色的手套; 然允许在所有人之间交换手套; (每个人 ...
- 【42.07%】【codeforces 558A】Lala Land and Apple Trees
time limit per test1 second memory limit per test256 megabytes inputstandard input outputstandard ou ...
- 【codeforces 546E】Soldier and Traveling
time limit per test1 second memory limit per test256 megabytes inputstandard input outputstandard ou ...
- 【codeforces 752F】Santa Clauses and a Soccer Championship
time limit per test2 seconds memory limit per test256 megabytes inputstandard input outputstandard o ...
- 【27.66%】【codeforces 592D】Super M
time limit per test2 seconds memory limit per test256 megabytes inputstandard input outputstandard o ...
- 【codeforces 761B】Dasha and friends
time limit per test2 seconds memory limit per test256 megabytes inputstandard input outputstandard o ...
- 【codeforces 762B】USB vs. PS/2
time limit per test2 seconds memory limit per test256 megabytes inputstandard input outputstandard o ...
- 【codeforces div3】【E. Cyclic Components】
E. Cyclic Components time limit per test 2 seconds memory limit per test 256 megabytes input standar ...
随机推荐
- EOS开发入门
EOS开发入门 在上一篇文章<EOS开发环境搭建>中,我们已经完成了EOS开发环境的搭建,本次为大家带来的是EOS开发入门的相关内容. 1. EOS的合约开发基础 智能合约是一种旨 ...
- c# 创建excel表头及内容
主要通过ajax调用函数Getinfo 1.定义表dh DataTable dh = new DataTable(); 2.创建表头 public void CreateCol(string Colu ...
- 【shell实例】定时21:00-21:05,循环调用DSQL脚本,其它时段自动退出
1.功能描述: 每日21:00定时调起test.sh,循环调起DSQL脚本test.dsql,直到21:05程序自动退出,捕获日志到相应log文件中. 2.日志文件: (1)日期.log文件中含Err ...
- angularjs html 转义
angularjs html 转义 默认情况下,AngularJS对会对插值指令求职表达式(模型)中的任何HTML标记都进行转义,例如以下模型: $scope.msg = “hello,<b&g ...
- log4net:ERROR XmlHierarchyConfigurator: Cannot find Property [File] to set object on [TF.Log.FileAppender]
难受,香菇. 大概研究了两个多小时,搜了很多资料都没有很完美的答案,最后突然脑子就一闪一闪,才弄明白咋回事. log4net:ERROR XmlHierarchyConfigurator: Canno ...
- 【深色模式】macOS Mojave+Visual Studio for Mac+FineUICore多图赏析!
全面开启深色模式,今早成功升级到 macOS Mojave,下面就来欣赏一下吧. 点击图片,查看大图 1. 下载 macOS Mojave 2. 安装成功,开启深色模式 3. 来一张桌面截图 4. 开 ...
- Python函数的装饰器修复技术(@wraps)
@wraps 函数的装饰器修复技术,可使被装饰的函数在增加了新功能的前提下,不改变原函数名称,还继续使用原函数的注释内容: 方便了上下文环境中不去更改原来使用的函数地方的函数名: 使用方法 from ...
- jeecg入门操作—模板配置(录入界面)
点击online表单的模板配置,进入模板设计列表页面,点击创建模板 点击创建模板 点击激活 设计完成,点击激活(表单模板可以多个,激活状态只能有一个) 激活后,重新加入功能测试,点击添加页面,效果如下 ...
- Node.js中的console.log()输出彩色字体
转自:https://www.jianshu.com/p/cca3e72c3ba7 console.log('\033[42;30m DONE \033[40;32m Compiled success ...
- Ubuntu安装Navicat 12 for MySQL
环境准备 要想运行Navicat,必须先安装Wine,这个可以使用下面的命令来安装Wine: ubuntu@ubuntu ~ $ sudo apt-get install wine-stable 安装 ...