1 条题解
-
0
#include<iostream> #include<cstdio> #include<algorithm> #include<cstring> #include<cmath> using namespace std; typedef long long ll; inline int read() { int x=0,f=1; char ch=getchar(); while(ch<'0'||ch>'9') { if(ch=='-') f=-1; ch=getchar(); } while(ch>='0'&&ch<='9') { x=(x<<1)+(x<<3)+(ch^48); ch=getchar(); } return x*f; } const int N=2e6+7; int n; double ans; int dfn[N],pos[N],sum[N];//sum是差分数组 //dfn是节点的dfs序,pos是dfn的反数组,所以有 pos[dfn[i]]=i,dfn[pos[i]]=i inline void mark(int x,int y) { sum[x]++,sum[y+1]--; }//打差分标记 int main() { // freopen("1.in","r",stdin); n=read(); ans=1; mark(1,1);//第一个节点一定要分一层 for(int i=1;i<=n;i++) dfn[read()]=i;//读入初始dfs序 for(int i=1;i<=n;i++) pos[dfn[read()]]=i;//用初始dfs序更新变化后的pos //上面一行不太好想。因为bfs序重标号了,原来的节点read()就变成了i,所以pos[dfn[read()]]=i for(int i=1;i<=n;i++) dfn[pos[i]]=i;//用更新后的pos更新dfn for(int i=1;i<n;i++)//注意i不取n { if(dfn[i]>dfn[i+1]) ans++,mark(i,i);//注意这里也要打标记,之后不会再产生0.5的贡献 if(pos[i]<pos[i+1]-1) mark(pos[i],pos[i+1]-1);//打标记 } int now=0; for(int i=1;i<n;i++) now+=sum[i],ans+=(now ? 0 : 0.5);//如果这个位置不确定则贡献为0.5 //注意上一行i不取n,因为切的位置只有n-1个 ans+=1;//深度等于分的段数+1 // printf("%.3lf\n%.3lf\n%.3lf",ans-0.001,ans,ans+0.001);//BZOJ上要这样输出... printf("%.3lf\n",ans); return 0; }
- 1
信息
- ID
- 233
- 时间
- 1000ms
- 内存
- 125MiB
- 难度
- 6
- 标签
- 递交数
- 2
- 已通过
- 2
- 上传者