题目链接
https://www.lydsy.com/JudgeOnline/problem.php?id=3244
思路
这道题bzoj需要输出ans-0.001,ans,ans+0.001……
考虑将bfs序钦点为1~n,dfs序对答案产生的贡献。
设重新编号后dfs序为,dfs序对应的bfs序中的位置为,那么:
如果
此时,显然与一定不在同一层,对深度的贡献为。
否则,考虑和在同一层的条件
考虑对于和,必定是的儿子,或者是的某个祖先的儿子,因此可以得到一组形如的不等式,就是说到的贡献小于等于,因此可以固定一些点的贡献为。
否则,对深度的期望贡献为。
代码
#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;
}