当前位置: 首页 > news >正文

LOJ2541:「PKUWC2018」猎人杀

传送门

Sol

第一步就不会

  1. 问题转化
    杀人后将其打上标记,仍可以以他为目标重复选,直到选到一个未打标记的人。
    这和原问题等价,而且这样每轮选中每人的概率都不变,只是游戏变成了无穷轮数
    这样就好做多了
  2. 考虑容斥,枚举在 \(1\) 后面被标记的猎人集合 \(S\),设其 \(w\) 的和为 \(A\),总的 \(w\) 的和为 \(B\),那么
    \[ans=\sum_{S}(-1)^{|S|}\frac{w_1}{B}\sum_{i=0}^{\infty}(1-\frac{A+w_1}{B})^i=\sum_{S}(-1)^{|S|}\frac{w_1}{A+w_1}\]

那么只要算出每个和为 \(A\) 的容斥系数的和就好了
这个可以直接 \(NTT\) 预处理 \(\prod_{i=2}^{n}(1-x^{w_i})\)
可以直接分治 \(FFT\)\(\Theta(nlog^2n)\),也可以求 \(ln\) 之后 \(exp\) \(\Theta(nlogn)\)
垃圾exp大常数被分治FFT吊着打

# include <bits/stdc++.h>
using namespace std;
typedef long long ll;

const int maxn(1 << 18);
const int mod(998244353);

inline void Inc(int &x, int y) {
    if ((x += y) >= mod) x -= mod;
}

inline int Pow(ll x, ll y) {
    register ll ret = 1;
    for (x %= mod, y %= mod - 1; y; y >>= 1, x = x * x % mod)
        if (y & 1) ret = ret * x % mod;
    return ret;
}

int w[2][maxn], r[maxn], l, deg;

inline void Init(int n) {
    register int i, x, y;
    for (deg = 1, l = 0; deg < n; deg <<= 1) ++l;
    for (i = 0; i < deg; ++i) r[i] = (r[i >> 1] >> 1) | ((i & 1) << (l - 1));
    w[1][0] = w[0][0] = 1, x = Pow(3, (mod - 1) / deg), y = Pow(x, mod - 2);
    for (i = 1; i < deg; ++i) w[0][i] = (ll)w[0][i - 1] * x % mod, w[1][i] = (ll)w[1][i - 1] * y % mod;
}

inline void NTT(int *p, int opt) {
    register int i, j, k, t, wn, x, y;
    for (i = 0; i < deg; ++i) if (r[i] < i) swap(p[r[i]], p[i]);
    for (i = 1; i < deg; i <<= 1)
        for(t = i << 1, j = 0; j < deg; j += t)
            for (k = 0; k < i; ++k) {
                wn = w[opt == -1][deg / (i << 1) * k];
                x = p[j + k], y = (ll)wn * p[i + j + k] % mod;
                p[j + k] = x + y, p[i + j + k] = x - y;
                if (p[j + k] >= mod) p[j + k] -= mod;
                if (p[i + j + k] < 0) p[i + j + k] += mod;
            }
    if (opt == -1) {
        for (wn = Pow(deg, mod - 2), i = 0; i < deg; ++i) p[i] = 1LL * p[i] * wn % mod;
    }
}

void Inv(int *p, int *q, int len) {
    if (len == 1) {
        q[0] = Pow(p[0], mod - 2);
        return;
    }
    Inv(p, q, len >> 1);
    register int i, tmp = len << 1;
    static int a[maxn], b[maxn];
    for (Init(tmp), i = 0; i < tmp; ++i) a[i] = b[i] = 0;
    for (i = 0; i < len; ++i) a[i] = p[i], b[i] = q[i];
    for (NTT(a, 1), NTT(b, 1), i = 0; i < tmp; ++i) a[i] = (ll)a[i] * b[i] % mod * b[i] % mod;
    for (NTT(a, -1), i = 0; i < len; ++i) q[i] = ((ll)q[i] + q[i] - a[i] + mod) % mod;
}

inline void Ln(int *p, int *q, int len) {
    register int i, tmp = len << 1;
    static int a[maxn], b[maxn];
    for (Init(tmp), i = 0; i < tmp; ++i) a[i] = b[i] = 0;
    for (Inv(p, b, len), i = 1; i < len; ++i) a[i - 1] = (ll)p[i] * i % mod;
    for (NTT(a, 1), NTT(b, 1), i = 0; i < tmp; ++i) a[i] = (ll)a[i] * b[i] % mod;
    for (NTT(a, -1), i = 0; i < len; ++i) q[i + 1] = (ll)a[i] * Pow(i + 1, mod - 2) % mod;
    q[0] = q[len] = 0;
}

void Exp(int *p, int *q, int len) {
    if (len == 1) {
        q[0] = 1;
        return;
    }
    Exp(p, q, len >> 1);
    register int i, tmp = len << 1;
    static int a[maxn], b[maxn];
    for (Init(tmp), i = 0; i < tmp; ++i) a[i] = b[i] = 0;
    for (Ln(q, a, len), i = 0; i < len; ++i) a[i] = (mod - a[i]) % mod;
    for (Inc(a[0], 1), i = 0; i < len; ++i) Inc(a[i], p[i]), b[i] = q[i];
    for (NTT(a, 1), NTT(b, 1), i = 0; i < tmp; ++i) a[i] = (ll)a[i] * b[i] % mod;
    for (NTT(a, -1), i = 0; i < len; ++i) q[i] = a[i];
}

int n, cnt[maxn], mx, len, f[maxn], g[maxn], inv[maxn], ans, a[maxn];

int main() {
    register int i, j;
    for (scanf("%d%d", &n, &a[0]), i = 1; i < n; ++i) scanf("%d", &a[i]), ++cnt[a[i]], mx += a[i];
    for (len = 1; len <= mx; len <<= 1);
    for (inv[1] = 1, i = 2; i <= mx; ++i) inv[i] = (ll)(mod - mod / i) * inv[mod % i] % mod;
    for (i = 1; i <= mx; ++i)
        if (cnt[i])
            for (j = i; j <= mx; j += i) Inc(f[j], mod - (ll)cnt[i] * inv[j / i] % mod);
    for (Exp(f, g, len), i = 0; i <= mx; ++i)
        if (g[i]) Inc(ans, (ll)g[i] * a[0] % mod * Pow(a[0] + i, mod - 2) % mod);
    printf("%d\n", ans);
    return 0;
}

转载于:https://www.cnblogs.com/cjoieryl/p/10137943.html

相关文章:

  • Redis 二:入门基本篇
  • 2019预测:三大专家视角解读云计算、无服务器等关键趋势
  • mysql学习笔记--第1天
  • Flink-数据流编程模型
  • 最全的Android开发资源整理--进阶必备
  • Zookeeper请求处理
  • yii2 render和renderPartial区别
  • [20181219]script使用小技巧.txt
  • “寻梦之路 阿里之行”北城大数据学院学生代表团赴北京阿里中心参观
  • 二叉搜索树
  • BestCoder Round #1 第一题 逃生
  • Protobuf3语言指南
  • 智能网联汽车信息安全
  • C语言函数栈
  • weex踩坑之旅第一弹 ~ 搭建具有入口文件的weex脚手架
  • “寒冬”下的金三银四跳槽季来了,帮你客观分析一下局面
  • C++11: atomic 头文件
  • CSS中外联样式表代表的含义
  • Druid 在有赞的实践
  • Java面向对象及其三大特征
  • MyEclipse 8.0 GA 搭建 Struts2 + Spring2 + Hibernate3 (测试)
  • Redis 懒删除(lazy free)简史
  • SpiderData 2019年2月23日 DApp数据排行榜
  • ucore操作系统实验笔记 - 重新理解中断
  • uni-app项目数字滚动
  • Vim 折腾记
  • 仿天猫超市收藏抛物线动画工具库
  • 好的网址,关于.net 4.0 ,vs 2010
  • 基于web的全景—— Pannellum小试
  • 模仿 Go Sort 排序接口实现的自定义排序
  • 如何学习JavaEE,项目又该如何做?
  • 深度解析利用ES6进行Promise封装总结
  • 深度学习入门:10门免费线上课程推荐
  • 思考 CSS 架构
  • 算法系列——算法入门之递归分而治之思想的实现
  • 限制Java线程池运行线程以及等待线程数量的策略
  • SAP CRM里Lead通过工作流自动创建Opportunity的原理讲解 ...
  • 浅谈sql中的in与not in,exists与not exists的区别
  • #周末课堂# 【Linux + JVM + Mysql高级性能优化班】(火热报名中~~~)
  • (3)Dubbo启动时qos-server can not bind localhost22222错误解决
  • (Spark3.2.0)Spark SQL 初探: 使用大数据分析2000万KF数据
  • (考研湖科大教书匠计算机网络)第一章概述-第五节1:计算机网络体系结构之分层思想和举例
  • (论文阅读22/100)Learning a Deep Compact Image Representation for Visual Tracking
  • (全部习题答案)研究生英语读写教程基础级教师用书PDF|| 研究生英语读写教程提高级教师用书PDF
  • .NET DevOps 接入指南 | 1. GitLab 安装
  • .NET MAUI学习笔记——2.构建第一个程序_初级篇
  • .NET Standard / dotnet-core / net472 —— .NET 究竟应该如何大小写?
  • .NET 编写一个可以异步等待循环中任何一个部分的 Awaiter
  • .NET:自动将请求参数绑定到ASPX、ASHX和MVC(菜鸟必看)
  • .net开发时的诡异问题,button的onclick事件无效
  • @font-face 用字体画图标
  • @synthesize和@dynamic分别有什么作用?
  • []新浪博客如何插入代码(其他博客应该也可以)
  • [Android] 240204批量生成联系人,短信,通话记录的APK
  • [BJDCTF2020]The mystery of ip