题目链接
https://www.lydsy.com/JudgeOnline/problem.php?id=3244
思路
这道题bzoj需要输出ans-0.001,ans,ans+0.001……
考虑将bfs序钦点为1~n,dfs序对答案产生的贡献。
设重新编号后dfs序为 D D ,dfs序对应的bfs序中的位置为,那么:
如果 pi−1>pi p i − 1 > p i
此时, i i 显然与一定不在同一层,对深度的贡献为 1 1 。
否则,考虑和 Di−1 D i − 1 在同一层的条件
考虑对于 Di−1 D i − 1 和 Di D i , Di D i 必定是 Di−1 D i − 1 的儿子,或者是 Di−1 D i − 1 的某个祖先的儿子,因此可以得到一组形如 deepDi−deepDi−1≤1 d e e p D i − d e e p D i − 1 ≤ 1 的不等式,就是说 Di−1+1 D i − 1 + 1 到 Di D i 的贡献小于等于 1 1 ,因此可以固定一些点的贡献为。
否则,对深度的期望贡献为 0.5 0.5 。
代码
#include <cstdio>
const int maxn=200000;
int read()
{
int x=0,f=1;
char ch=getchar();
while((ch<'0')||(ch>'9'))
{
if(ch=='-')
{
f=-f;
}
ch=getchar();
}
while((ch>='0')&&(ch<='9'))
{
x=x*10+ch-'0';
ch=getchar();
}
return x*f;
}
int d[maxn+10],s[maxn+10],c[maxn+10],pos[maxn+10],v[maxn+10],n;
double ans;
int main()
{
n=read();
for(int i=1; i<=n; ++i)
{
d[read()]=i;
}
for(int i=1; i<=n; ++i)
{
pos[i]=d[read()];
}
for(int i=1; i<=n; ++i)
{
d[pos[i]]=i;
}
v[2]=1;
c[2]=1;
c[3]=-1;
for(int i=2; i<=n; ++i)
{
if(pos[i-1]>pos[i])
{
v[i]=1;
++c[i];
--c[i+1];
}
}
for(int i=2; i<=n; ++i)
{
s[i]=s[i-1]+v[i];
}
for(int i=2; i<=n; ++i)
{
if((d[i-1]<d[i])&&(s[d[i]]-s[d[i-1]]))
{
++c[d[i-1]+1];
--c[d[i]+1];
}
}
int t=0;
ans=1;
for(int i=2; i<=n; ++i)
{
t+=c[i];
if(t)
{
ans+=v[i];
}
else
{
ans+=0.5;
}
}
printf("%.3lf\n%.3lf\n%.3lf\n",ans-0.001,ans,ans+0.001);
return 0;
}