题目大意:给出一个森林,每次询问给出u,v,问从u所在连通块中随机选出一个点与v所在连通块中随机选出一个点相连,连出的树的直径期望(不是树输出-1)。(n,q<=10^5)

解法:预处理出各连通块的直径和各点到连通块内一点的最远距离d[x](树形dp+换根),询问若在同一块内输出-1,否则若随机选出两点x,y,直径为max(d[x]+d[y]+1,x所在块直径,y所在块直径),我们把同一连通块内的d排序,枚举小的连通块中的d,到大的连通块中二分d[x]+d[y]+1<=max(x所在块直径,y所在块直径)(或者记下大的块中每种权值出现次数,从max直径开始d[x]递增d[y]递减,复杂度少一个log并仍然只与小的块的大小相关),记忆下相同询问,这样我们枚举小的次数最大只有$O(n^{1.5})$(每次我们复杂度只跟小的有关,那么最劣情况只有每次两个块大小相等,假设所有联通块大小均为k,我们的复杂度是$O(k*min(q,(\frac{n}{k})^2))$,容易证明复杂度最大是$O(n^{1.5})$)。

#include<cstdio>
#include<algorithm>
#include<vector>
#include<map>
using namespace std;
inline int read()
{
int x;char c;
while((c=getchar())<''||c>'');
for(x=c-'';(c=getchar())>=''&&c<='';)x=(x<<)+(x<<)+c-'';
return x;
}
#define MN 100000
#define p(x,y) make_pair(x,y)
struct edge{int nx,t;}e[MN*+];
int f[MN+],h[MN+],en,d[MN+],d2[MN+],mx[MN+];
vector<double> v[MN+];
map<pair<int,int>,double> mp;
int gf(int k){return f[k]?f[k]=gf(f[k]):k;}
inline void ins(int x,int y)
{
e[++en]=(edge){h[x],y};h[x]=en;
e[++en]=(edge){h[y],x};h[y]=en;
}
void upd(int x,int y)
{
if(y>d[x])d2[x]=d[x],d[x]=y;
else if(y>d2[x])d2[x]=y;
}
void dp(int x,int fa)
{
for(int i=h[x];i;i=e[i].nx)if(e[i].t!=fa)
dp(e[i].t,x),upd(x,d[e[i].t]+);
mx[gf(x)]=max(mx[gf(x)],d[x]+d2[x]);
}
void dfs(int x,int fa)
{
v[gf(x)].push_back(d[x]);
for(int i=h[x];i;i=e[i].nx)if(e[i].t!=fa)
upd(e[i].t,d[e[i].t]+==d[x]?d2[x]+:d[x]+),dfs(e[i].t,x);
}
int main()
{
int n,m,q,x,y,i,j,l,r,mid,res;double ans;
n=read();m=read();q=read();
while(m--)ins(x=read(),y=read()),f[gf(x)]=gf(y);
for(i=;i<=n;++i)if(gf(i)==i)
{
dp(i,i);dfs(i,i);v[i].push_back();
sort(v[i].begin(),v[i].end());
for(j=;j<v[i].size();++j)v[i][j]+=v[i][j-];
}
while(q--)
{
if((x=gf(read()))==(y=gf(read()))){puts("-1");continue;}
if(x>y)swap(x,y);
if(mp[p(x,y)]){printf("%.10lf\n",mp[p(x,y)]);continue;}
if(v[x].size()>v[y].size())swap(x,y);
for(i=,ans=;i<v[x].size();++i)
{
for(l=,r=v[y].size()-,res=;l<=r;)
{
mid=l+r>>;
if(v[x][i]-v[x][i-]+v[y][mid]-v[y][mid-]+<=max(mx[x],mx[y]))
res=mid,l=mid+;
else r=mid-;
}
ans+=(double)res*max(mx[x],mx[y])+
(v[y].size()--res)*(v[x][i]-v[x][i-]+)+v[y][v[y].size()-]-v[y][res];
}
if(x>y)swap(x,y);
printf("%.10lf\n",mp[p(x,y)]=ans/(v[x].size()-)/(v[y].size()-));
}
}

Codeforces Round #411 (Div. 1) D. Expected diameter of a tree的更多相关文章

  1. Codeforces Round #411 (Div. 2)

    来自FallDream的博客,未经允许,请勿转载,谢谢. 由于人傻又菜 所以这次又滚去div2了  一堆结论题真的可怕 看见E题不是很有思路   然后就去大力搞F题  T了最后一个点 真的绝望   但 ...

  2. Codeforces Round #411 (Div. 2) A-F

    比赛时候切了A-E,fst了A Standings第一页只有三个人挂了A题,而我就是其中之一,真™开心啊蛤蛤蛤 A. Fake NP time limit per test 1 second memo ...

  3. Codeforces Round 411 Div.2 题解

    A Fake NP standard input/output s, MB Submit Add to favourites x3673 B -palindrome standard input/ou ...

  4. Codeforces Round #411 (Div. 2)(A,B,C,D 四水题)

    A. Fake NP time limit per test:1 second memory limit per test:256 megabytes input:standard input out ...

  5. Codeforces Round #411 div 2 D. Minimum number of steps

    D. Minimum number of steps time limit per test 1 second memory limit per test 256 megabytes input st ...

  6. Codeforces Round #411 (Div. 2) 【ABCDE】

    A. Fake NP 题意:给你l,r,让你输出[l,r]里面除1以外的,出现因子数量最多的那个数. 题解:如果l==r输出l,否则都输出2 #include<bits/stdc++.h> ...

  7. Codeforces Round #411 (Div. 2) C. Find Amir

    C. Find Amir time limit per test   1 second memory limit per test   256 megabytes   A few years ago ...

  8. 【DFS】【贪心】Codeforces Round #411 (Div. 1) C. Ice cream coloring

    对那个树进行dfs,在动态维护那个当前的冰激凌集合的时候,显然某种冰激凌仅会进出集合各一次(因为在树上形成连通块). 于是显然可以对当前的冰激凌集合贪心染色.暴力去维护即可.具体实现看代码.map不必 ...

  9. 【推导】Codeforces Round #411 (Div. 1) B. Minimum number of steps

    最后肯定是bbbb...aaaa...这样. 你每进行一系列替换操作,相当于把一个a移动到右侧. 会增加一些b的数量……然后你统计一下就行.式子很简单. 喵喵喵,我分段统计的,用了等比数列……感觉智障 ...

随机推荐

  1. 201621123040《Java程序设计》第六周学习总结

    1.本周学习总结 1.1 面向对象学习暂告一段落,请使用思维导图,以封装.继承.多态为核心概念画一张思维导图或相关笔记,对面向对象思想进行一个总结 2.书面作业 2.1clone方法 2.1.1在te ...

  2. 400多个开源项目以及43个优秀的Swift开源项目-Swift编程语言资料大合集

    Swift 基于C和Objective-C,是供iOS和OS X应用编程的全新语言,更加高效.现代.安全,可以提升应用性能,同时降低开发难度. Swift仍然处于beta测试的阶段,会在iOS 8发布 ...

  3. iOS 播放音频的几种方法

    Phone OS 主要提供以下了几种播放音频的方法: System Sound Services AVAudioPlayer 类 Audio Queue Services OpenAL 1. Syst ...

  4. 关于安装win7系统时出现0x0000007b电脑蓝屏代码的问题

    问题解析: 0X0000007B 这个错误网上都说是sata硬盘的什么引导模式的原因引起. 在网上查找了很久,大概引起错误的原因就是:sata和ide两种模式不同,前者可以装win7系统,后者是xp系 ...

  5. codves 3044 矩形面积求并

    codves  3044 矩形面积求并  题目等级 : 钻石 Diamond 题目描述 Description 输入n个矩形,求他们总共占地面积(也就是求一下面积的并) 输入描述 Input Desc ...

  6. react基础篇入门组件

    讲述一下React: 1.声明式设计-React采用声明范式,可以轻松描述应用 2.高效-React通过DOM模型,最大限度的减少dom的交互 3.灵活-React可以与已知的库或框架很好的配合 4. ...

  7. 【编程开发】PHP---面向对象

    面向对象编程 类:在现实世界中,任何事物都有种类的概念:车 类是由特征和行为构成的. 特征:都是不动的,从出厂的时候就已经内置好了(属性) 行为:一种动的状态.(方法(函数)) 行为依赖于这些特征,而 ...

  8. windows安装gcc编译器

    由于vc6.0对c语言编译不是很好,有些语句是正确的,但是编译却不能通过 所以决定在windows中安装gcc编译器来使用! http://www.cnblogs.com/cryinstall/arc ...

  9. js的构造函数共用事例

    在使用构造函数去实现一种功能时,我们有时候往往需要实现这个功能,会因此产生多个堆内对象.这样就会造成堆内存滥用.占用不该占用的空间.为此我们可以利用函数把共用的内容封装起来.放便我们的使用.很多东西其 ...

  10. Python内置函数(58)——input

    英文文档: input([prompt]) If the prompt argument is present, it is written to standard output without a ...