首页 > 其他分享 >[ABC216H] Random Robots

[ABC216H] Random Robots

时间:2025-01-03 11:46:30浏览次数:7  
标签:路径 ABC216H int Random Robots mul binom jc mod

[ABC216H] Random Robots

题意

有 \(k\) 个机器人在数轴上, 位置分别是 \(x_1,x_2,\dots,x_k\) , \(x\) 均为整数.

接下来 \(n\) 秒, 每秒每个机器人有 \(\dfrac{1}{2}\) 的概率不动, \(\dfrac{1}{2}\) 的概率往坐标轴正方向移动一个单位距离, 机器人的移动同时进行.

求机器人互相不碰撞的概率, 对 \(998244353\) 取模。

\(k \le 10,n,x \le 1000\)。

思路

相当于求不碰撞的方案数,最后除以 \(2^{nk}\)。

设终点位置是 \(y_i\)。

加一维时间维,即 \((x,y)\) 可以走到 \((x+1,y)\)(不走)或者 \((x+1,y+1)\)(向右走一步),不碰撞即路径没有公共点。

容易想到 LGV 引理。但是不能乱套哦。

假设我们已经确定了 \(\{y_i\}\)。且这是一个升序序列。这是一个分层图。

算每个 \(0,x_i\) 都走到 \(y_i\) 的方案数是好算的,就是 \(\prod_{i=1}^n \binom{n}{y_i-x_i}\)。

那么他们在中间相交怎么办呢?

经典容斥,要求两条路径不交的方案数,就用 \(至少交0次的方案数 - 至少交1次的方案数\)。求至少交一次的方案数,就是交换两条路径的终点,然后求无限制的方案数。

多条路径怎么做呢?就用 \(至少0对路径有交点 - 至少1对路径有交点 + 至少2对路径有交点 \cdots\)。

即对一个升序序列 \(\{y_i\}\),答案就是 \(\sum_{p} (-1)^{sgn(p)} \prod_{i=1}^n \omega((0,x_i),(n,y_{p_i}))\)。

其中 \(sgn(p)\) 表示排列 \(p\) 的逆序对数。\(\omega((0,x),(n,y))=\binom{n}{y-x}\)。

根据 LGV 引理,可以求个行列式来计算。然而显然我们不能枚举 \(\{y_i\}\)。

注意到数据范围,考虑状压 DP。

设 \(f_{i,s}\) 表示处理到坐标 \(i\),目前已经有状态为 \(s\) 的起点已经确定了终点,的合法方案数。状态数是 \(O(2^k x)\) 的。

转移就是枚举是否有一个起点选择位置 \(i\) 作为终点(显然合法方案不会有两个起点走到一个位置作为终点)。

枚举哪个起点选择 \(i\) 作为终点,新贡献的逆序对数是好算的,对连乘的贡献也是好算的。即:

\[f_{i,s} \gets f_{i-1,s}(不选)\\ f_{i,s\cup j} \gets (-1)^{cnt} \binom{n}{i-x_j} f_{i-1,s} (选j) \]

其中 \(cnt\) 指新增逆序对个数,即 \(s\) 的低 \(j-1\) 位里面有多少个 \(0\)。

答案就是 \(f_{x,2^k-1}\)。

时间复杂度 \(O(2^k x k)\)。

code

#include<bits/stdc++.h>
#define sf scanf
#define pf printf
#define rep(x,y,z) for(int x=y;x<=z;x++)
#define per(x,y,z) for(int x=y;x>=z;x--)
using namespace std;
typedef long long ll;
namespace pragmatic {
    constexpr int N=15,V=2e3+1,mod=998244353;
    int add(int a,int b) { return a+b>=mod ? a+b-mod : a+b; }
    void _add(int &a,int b) { a=add(a,b); }
    int mul(int a,int b) { return 1ll*a*b%mod; }
    void _mul(int &a,int b) { a=mul(a,b); }
    int ksm(int a,int b=mod-2) {
        int s=1;
        while(b) {
            if(b&1) _mul(s,a);
            _mul(a,a);
            b>>=1;
        }
        return s;
    }
    int jc[V+7],inv[V+7];
    void init() {
        jc[0]=1;
        rep(i,1,V) jc[i]=mul(jc[i-1],i);
        inv[V]=ksm(jc[V]);
        per(i,V-1,0) inv[i]=mul(inv[i+1],i+1);
    }
    int binom(int n,int m) {
        if(n<m || m<0) return 0;
        return mul(jc[n],mul(inv[m],inv[n-m]));
    }
    int k,n,x[N];
    int f[V+7][V+7];
    void main() {
        sf("%d%d",&k,&n);
        rep(i,1,k) sf("%d",&x[i]), ++x[i];
        init();
        f[0][0]=1;
        rep(i,1,V) {
            rep(j,0,(1<<k)-1) {
                if(!f[i-1][j]) continue;
                _add(f[i][j],f[i-1][j]);
                int cnt=0;
                rep(p,1,k) {
                    if(!((j>>(p-1))&1)) {
                        int tmp=mul(f[i-1][j],binom(n,i-x[p]));
                        if(tmp) _add(f[i][j^(1<<(p-1))],cnt ? mod-tmp : tmp);
                        cnt^=1;
                    }
                }
            }
        }
        pf("%d\n",mul(f[V][(1<<k)-1],ksm(ksm(2,n*k))));
    }
}
int main() {
    #ifdef LOCAL
    freopen("in.txt","r",stdin);
    freopen("my.out","w",stdout);
    #endif
    pragmatic :: main();
}

标签:路径,ABC216H,int,Random,Robots,mul,binom,jc,mod
From: https://www.cnblogs.com/liyixin0514/p/18649683

相关文章

  • random.choice() 和 random.random.choices()的用法区别
    random.choice()和random.choices()是Python标准库random模块中用于随机选择的两个函数,但它们的用法和功能有所不同。random.choice()random.choice()用于从一个非空序列(如列表、元组或字符串)中随机选择一个元素。语法random.choice(seq)seq:一个非空序列。示例i......
  • 【重要】random随机库函数用法示例
    根据以下列表,从序号、函数名、用途、示例,用表格显示每个函数的信息['betavariate','choice','choices','expovariate','gammavariate','gauss','getrandbits','getstate','lognormvariate','nor......
  • UserCryptoManager.getRandomValues
    UserCryptoManager.getRandomValues(Objectobject)基础库2.17.3开始支持,低版本需做兼容处理。以Promise风格调用:不支持小程序插件:不支持相关文档:小程序加密网络通道功能描述获取密码学安全随机数参数Objectobject属性类型默认值必填说明lengt......
  • 解释下`(~~(Math.random()*(1<<24)))`的含义
    这段代码(~~(Math.random()*(1<<24)))在前端开发中可能用于生成一个随机整数。下面我们来分解这段代码,以更好地理解其含义:Math.random():这个函数返回一个[0,1)之间的随机浮点数,也就是说,它会返回一个大于等于0且小于1的随机小数。1<<24:这是一个位移运算。1左移24位,等......
  • random.normalvariate函数
    random.normalvariate函数random.normalvariate是Python内置random模块中的一个函数,用于从正态分布(高斯分布)中生成随机样本。与SciPy提供的norm.rvs类似,它是一种高效的采样方法,适合简单的正态分布模拟。1.函数定义random.normalvariate(mu,sigma)参数说明......
  • html5中的meta标签robots有什么作用?
    在HTML5中,<meta>标签的robots属性(通常被称为robotsmeta标签)主要用于控制搜索引擎机器人(也称为网络爬虫或蜘蛛)如何索引和跟踪网页。这个标签通常放在HTML文档的<head>部分。robotsmeta标签可以包含多个值,这些值以逗号分隔,用于指示搜索引擎如何处理该页面。以下是一些常见的值:i......
  • random file
    下面是对这个问题进行深入分析后的一种思考和可能的解决方向(并非最终定稿答案,仅为参考思路)。问题本身需要在每次操作(插入或删除一条鱼)后,求出当前鱼群中在最优策略下最多能产生的危险打斗次数。问题重述:我们有一个动态维护的鱼群集合,每条鱼有一个重量(a_i)。打斗规则为:每一轮......
  • 【java】 随笔 charAt,Random,ArrayList
    1.charAtcharch=str.charAt(i)  根据索引来获取字符串中的字符到ch中2.Random       Random类用来生成随机数字    (1)导包        importjava.util.Random;    (2)创建         Randomr=newRand......
  • Improved LiDAR Localization Method for Mobile Robots Based on Multi-Sensing
    ImprovedLiDARLocalizationMethodforMobileRobotsBasedonMulti-Sensing哈尔滨工业大学机电工程系机器人与系统国家重点实验室,哈尔滨150001*通讯地址:21b908026@stu.hit.edu.cn刘艳杰、王超*、吴恒、魏彦龙、任美轩、赵长森MDPIRemotesensing摘要:本文通过......
  • Python模块之random、hashlib、json、time等内置模块语法学习
    Python内置模块语法学习random、hashlib、json、time、datetime、os等内置模块语法学习模块简单理解为就是一个.py后缀的一个文件分为三种:内置模块:python自带,可调用第三方模块:别人设计的,可调用自定义模块:自己编写的,可调用模块之间苦于相互调用,是Python最高级别的组织......