BZOJ 4675(点分治)

本文详细解析了一种计算幸运点对期望值的算法,利用概率论中的期望线性性原理,结合组合数学,推导出每个点对对答案的贡献公式,并通过点分治策略高效求解幸运点对数量,最终得出总期望值。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

题面

传送门

分析

由于期望的线性性,我们可以分别计算每个点对对答案的贡献

有三个人取数字,分开对每个人考虑

设每个人分别取了k个数,则一共有\(C_n^k\)种组合,选到每种组合的概率为\(\frac{1}{C_n^k}\)

对于一个幸运点对,包含它的组合有\(C_{n-2}^{k-2}\)种(k个点中有2个点是该点对,再从剩下的n-2个点中选k-2个点,每种的贡献均为1)

所以每一个点对的贡献是

\[\frac{C_{n-2}^{k-2}}{C_n^k}=\frac{\frac{(n-2)!}{(n-k)!\times (k-2)!}}{\frac{n!}{(n-k)! \times k !}}=\frac{(n-2)! \times k !}{n! \times (k-2)!}=\frac{k(k-1)}{n(n-1)}\]

因此总答案为\(a \times \frac{k(k-1)}{n(n-1)}\),其中a为幸运点对的数量

所以只要求出幸运点对数量即可

对于每一个幸运数num[i],我们进行一次点分治,求出长度为num[i]的路径数(直接套点分治板子,先求长度>=num[i]的路径数,再减去长度>num[i]的路径数量),并累计进答案

注意最后n*(n-1)要用double,否则会爆int

代码

#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#define maxn 50005 
using namespace std;


int n,k;
struct edge{
    int from;
    int to;
    int next;
}E[maxn<<1];
int ecnt=1;
int head[maxn];
inline void add_edge(int u,int v){
    ecnt++;
    E[ecnt].from=u;
    E[ecnt].to=v;
    E[ecnt].next=head[u];
    head[u]=ecnt;
}

int root=0,sum;
int f[maxn];
int sz[maxn];
int vis[maxn];
void get_root(int x,int fa){
    sz[x]=1;
    f[x]=0;
    for(int i=head[x];i;i=E[i].next){
        int y=E[i].to;
        if(y!=fa&&!vis[y]){
            get_root(y,x);
            sz[x]+=sz[y];
            f[x]=max(f[x],sz[y]);
        } 
    }
    f[x]=max(f[x],sum-f[x]);
    if(f[x]<f[root]) root=x; 
}

int cnt=0;
int deep[maxn];
int res[maxn];
void get_deep(int x,int fa){
    res[++cnt]=deep[x];
    for(int i=head[x];i;i=E[i].next){
        int y=E[i].to;
        if(y!=fa&&!vis[y]){
            deep[y]=deep[x]+1;
            get_deep(y,x);
        }
    }
}

int calc(int x,int d0){
    deep[x]=d0;
    cnt=0;
    get_deep(x,0);
    sort(res+1,res+1+cnt);
    int l=1,r=cnt;
    int ans1=0;
    while(l<r){
        if(res[l]+res[r]<=k){
            ans1+=(r-l);
            l++;
        }else r--;
    }
    
    l=1,r=cnt;
    int ans2=0;
    while(l<r){
        if(res[l]+res[r]<k){
            ans2+=(r-l);
            l++;
        }else r--;
    }
    return ans1-ans2;
}

int ans=0;
void solve(int x){
    vis[x]=1;
    ans+=calc(x,0);
    for(int i=head[x];i;i=E[i].next){
        int y=E[i].to;
        if(!vis[y]){
            ans-=calc(y,1);
            root=0;
            sum=sz[y];
            get_root(y,0);
            solve(root);
        }
    }
}

void divide_ini(){
    memset(deep,0,sizeof(deep));
    memset(f,0,sizeof(f));
    memset(sz,0,sizeof(sz));
    memset(vis,0,sizeof(vis));
    root=0;
    sum=n;
    f[0]=n;
    get_root(1,0);
}

int m;
int num[maxn];
int main(){
    int u,v;
    scanf("%d %d",&n,&m);
    for(int i=1;i<=m;i++){
        scanf("%d",&num[i]);
    }
    for(int i=1;i<n;i++){
        scanf("%d %d",&u,&v);
        add_edge(u,v);
        add_edge(v,u);
    }
    for(int i=1;i<=m;i++){
        k=num[i];
        divide_ini();
        solve(root); 
    }
    double k1,k2,k3;
    if(n%3==0) k1=k2=k3=n/3;
    else if(n%3==1){
        k1=n/3+1;
        k2=n/3;
        k3=n/3;
    }else{
        k1=n/3+1;
        k2=n/3+1;
        k3=n/3;
    }
    printf("%.2lf\n",ans*k1*(k1-1)/((double)n*(n-1)));//强制转成double,防止溢出
    printf("%.2lf\n",ans*k2*(k2-1)/((double)n*(n-1)));
    printf("%.2lf\n",ans*k3*(k3-1)/((double)n*(n-1)));
}

转载于:https://www.cnblogs.com/birchtree/p/10333939.html

内容概要:本文深入探讨了Kotlin语言在函数式编程和跨平台开发方面的特性和优势,结合详细的代码案例,展示了Kotlin的核心技巧和应用场景。文章首先介绍了高阶函数和Lambda表达式的使用,解释了它们如何简化集合操作和回调函数处理。接着,详细讲解了Kotlin Multiplatform(KMP)的实现方式,包括共享模块的创建和平台特定模块的配置,展示了如何通过共享业务逻辑代码提高开发效率。最后,文章总结了Kotlin在Android开发、跨平台移动开发、后端开发和Web开发中的应用场景,并展望了其未来发展趋势,指出Kotlin将继续在函数式编程和跨平台开发领域不断完善和发展。; 适合人群:对函数式编程和跨平台开发感兴趣的开发者,尤其是有一定编程基础的Kotlin初学者和中级开发者。; 使用场景及目标:①理解Kotlin中高阶函数和Lambda表达式的使用方法及其在实际开发中的应用场景;②掌握Kotlin Multiplatform的实现方式,能够在多个平台上共享业务逻辑代码,提高开发效率;③了解Kotlin在不同开发领域的应用场景,为选择合适的技术栈提供参考。; 其他说明:本文不仅提供了理论知识,还结合了大量代码案例,帮助读者更好地理解和实践Kotlin的函数式编程特性和跨平台开发能力。建议读者在学习过程中动手实践代码案例,以加深理解和掌握。
内容概要:本文深入探讨了利用历史速度命令(HVC)增强仿射编队机动控制性能的方法。论文提出了HVC在仿射编队控制中的潜在价值,通过全面评估HVC对系统的影响,提出了易于测试的稳定性件,并给出了延迟参数与跟踪误差关系的显式不等式。研究为两轮差动机器人(TWDRs)群提供了系统的协调编队机动控制方案,并通过9台TWDRs的仿真和实验验证了稳定性和综合性能改进。此外,文中还提供了详细的Python代码实现,涵盖仿射编队控制类、HVC增强、稳定性件检查以及仿真实验。代码不仅实现了论文的核心思想,还扩展了邻居历史信息利用、动态拓扑优化和自适应控制等性能提升策略,更全面地反映了群体智能协作和性能优化思想。 适用人群:具备一定编程基础,对群体智能、机器人编队控制、时滞系统稳定性分析感兴趣的科研人员和工程师。 使用场景及目标:①理解HVC在仿射编队控制中的应用及其对系统性能的提升;②掌握仿射编队控制的具体实现方法,包括控制器设计、稳定性分析和仿真实验;③学习如何通过引入历史信息(如HVC)来优化群体智能系统的性能;④探索中性型时滞系统的稳定性件及其在实际系统中的应用。 其他说明:此资源不仅提供了理论分析,还包括完整的Python代码实现,帮助读者从理论到实践全面掌握仿射编队控制技术。代码结构清晰,涵盖了从初始化配置、控制律设计到性能评估的各个环节,并提供了丰富的可视化工具,便于理解和分析系统性能。通过阅读和实践,读者可以深入了解HVC增强仿射编队控制的工作原理及其实际应用效果。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值