乒乓球

题目描述

小 BoBoBo 是某省乒乓球名列前茅的选手,现在他有 nnn 颗乒乓球一字排开,第iii颗乒乓球的权值为 wiw_iwi​
每次他会随机从现有的乒乓球中等概率选一颗拿走,然后得到的收益是这颗球左边第一个乒乓球和右边第一个乒乓球的权值的乘积,如果左边没有乒乓球或者右边没有乒乓球,则收益为 000,这个过程会重复进行到所有球都被拿走为止
现在小 BoBoBo 想知道他的期望总收益
为了方便,你只需要输出答案对 998244353998244353998244353 取模的值.

解决方案

思路就是枚举一对乒乓球(i,j)(i,j)(i,j)然后计算它对于答案的贡献.
(i,j)(i,j)(i,j)要想产生贡献,那么至少要满足2≤j−i≤n−12 \le j-i \le n-12≤j−i≤n−1.

考虑i,ji,ji,j两颗乒乓球一定要在[i+1,j−1][i+1,j-1][i+1,j−1]之间的乒乓球全都取完才能取,这样的情况共有(j−i−1)!∗2!∗Cnj−i+1∗(n−(j−i+1))!(j-i-1)!*2!*C_n^{j-i+1}*(n-(j-i+1))!(j−i−1)!∗2!∗Cnj−i+1​∗(n−(j−i+1))!

也就是2∗n!(j−i)(j−i+1)\frac{2*n!}{(j-i)(j-i+1)}(j−i)(j−i+1)2∗n!​,而最后的答案要除以n!n!n!,所以在这里直接除掉就可以了,也就是2(j−i)(j−i+1)\frac{2}{(j-i)(j-i+1)}(j−i)(j−i+1)2​

共线即为wi∗wj∗2(j−i)(j−i+1)w_i*w_j*\frac{2}{(j-i)(j-i+1)}wi​∗wj​∗(j−i)(j−i+1)2​

而这个值只与(j−i)(j-i)(j−i)的大小有关,而如果我们将式子中第二个wjw_jwj​反转,即改写成bn−jb_{n-j}bn−j​.(其中bi=wn−ib_i = w_{n-i}bi​=wn−i​)

那么wi∗bn−j∗2(j−i)(j−i+1)w_i*b_{n-j}*\frac{2}{(j-i)(j-i+1)}wi​∗bn−j​∗(j−i)(j−i+1)2​

这下我们枚举2(t)(t+1)\frac{2}{(t)(t+1)}(t)(t+1)2​,找所有满足的(i,n−j)(i,n-j)(i,n−j)对,使得n−j−i=n−tn-j-i = n-tn−j−i=n−t

显然这就是一个求卷积的裸题了,www序列与bbb序列卷积的第n−tn-tn−t项就是我们要求的答案.

代码

#include <iostream>
#include <cstring>
#include <cstdio>using namespace std;
typedef long long LL;
const int N = 1 << 20;
const int P = 998244353;
const int G = 3;
const int NUM = 20;LL  wn[NUM];
LL  a[N], b[N];LL quick_mod(LL a, LL b, LL m)
{LL ans = 1;a %= m;while(b){if(b & 1){ans = ans * a % m;b--;}b >>= 1;a = a * a % m;}return ans;
}void GetWn()
{for(int i = 0; i < NUM; i++){int t = 1 << i;wn[i] = quick_mod(G, (P - 1) / t, P);}
}
void Rader(LL a[], int len)
{int j = len >> 1;for(int i = 1; i < len - 1; i++){if(i < j) swap(a[i], a[j]);int k = len >> 1;while(j >= k){j -= k;k >>= 1;}if(j < k) j += k;}
}void NTT(LL a[], int len, int on)
{Rader(a, len);int id = 0;for(int h = 2; h <= len; h <<= 1){id++;for(int j = 0; j < len; j += h){LL w = 1;for(int k = j; k < j + h / 2; k++){LL u = a[k] % P;LL t = w * a[k + h / 2] % P;a[k] = (u + t) % P;a[k + h / 2] = (u - t + P) % P;w = w * wn[id] % P;}}}if(on == -1){for(int i = 1; i < len / 2; i++)swap(a[i], a[len - i]);LL inv = quick_mod(len, P - 2, P);for(int i = 0; i < len; i++)a[i] = a[i] * inv % P;}
}void Conv(LL a[], LL b[], int n)
{NTT(a, n, 1);NTT(b, n, 1);for(int i = 0; i < n; i++)a[i] = a[i] * b[i] % P;NTT(a, n, -1);
}
LL Fac[N];
int n;
int main()
{   Fac[0] = 1;for(int i = 1;i < N;++i) {Fac[i] = Fac[i-1] * i % P;}GetWn();std::cin >> n;for(int i = 0;i < n;++i){ std::cin >> a[i];b[n-i] = a[i];}int len = 1;while(len < n) len <<= 1;len <<= 1;Conv(a,b,len);LL ans = 0;for(int le = 2;le <= n-1;++le) {LL part = 2 * quick_mod(le,P-2,P) % P * quick_mod(le+1,P-2,P) % P;ans = (ans + (a[n-le]*part % P)) % P;}std::cout << ans << std::endl;return 0;
}

数学推导题,NTT,快速数论变换,Wannafly-乒乓球相关推荐

  1. 数学推导题,NTT,快速数论变换,Wannafly-导数卷积

    导数卷积 题目描述 题解 参考了一下标程的推导过程,因为这个推导对我这种数学弱渣真的有点难鸭. [1]f(x)f(x)f(x)的iii次导函数: f(i)(x)=ai∗i!0!+ai+1∗(i+1)! ...

  2. FFT 快速傅里叶变换 NTT 快速数论变换

    SDNU 1531 a*b III (FFT模板) Description 计算a乘b,多组输入(50组以内). Input 输入a b,数据范围0 <= a,b <= 10^100000 ...

  3. A*B NTT快速数论变换

    wmq的A×B Problem 发布时间: 2017年4月9日 17:06   最后更新: 2017年4月9日 17:07   时间限制: 3000ms   内存限制: 512M 描述 这是一个非常简 ...

  4. NTT(快速数论变换)模板

    NTT好文 NTT快速数论变换,在acm中用于解决一类多项式卷积问题. 多项式A和多项式B求卷积后的多项式为C. 显然,如果A是n次多项式,B有m次多项式,这两个多项式都不缺项的话,乘积应为n+m次多 ...

  5. 【学习笔记】超简单的快速数论变换(NTT)(FFT的优化)(含全套证明)

    整理的算法模板合集: ACM模板 目录 一.前置知识 二.快速数论变换(NTT) 三.NTT证明(和FFT的关系) 四.NTT模板 数组形式的实现 vector形式的实现 点我看多项式全家桶(●^◡_ ...

  6. 多项式算法2:NTT(快速数论变换)

    多项式算法2:NTT(快速数论变换) 前言 前置知识 正文 前言 算法简介 上次的FFT大量使用浮点数,有精度不好控制的问题,使用可以保证精度的方法又容易超时.这里NTT是在取模的一个前提下找到一个新 ...

  7. 比FFT还容易明白的NTT(快速数论变换)

    NTT相关 一种快速数论变换算法,这种算法是以数论为基础,对样本点为的数论变换,按时间抽取的方法,得到一组等价的迭代方程,有效高速简化了方程中的计算公式·与直接计算相比,大大减少了运算次数.(见快速傅 ...

  8. 算法学习FFT系列(2):快速数论变换NTT bzoj3992: [SDOI2015]序列统计例题详解

    bzoj3992: [SDOI2015]序列统计 Description 小C有一个集合S,里面的元素都是小于M的非负整数.他用程序编写了一个数列生成器,可以生成一个长度为N的数列,数列中的每个数都属 ...

  9. python蝴蝶代码_快速数论变换(NTT)及蝴蝶操作构造详解

    快速数论变换 本文不会从头开始介绍NTT算法,所以需要先了解FFT:永远在你身后:快速傅里叶变换(FFT)求解多项式乘法​zhuanlan.zhihu.com 除此之外,先简单的铺垫一些数论的概念同余 ...

最新文章

  1. CTFshow 命令执行 web77
  2. hdu 2988 Strange fuction【模拟退火】
  3. nodejs sqlite3_NodeJS 使用 better-sqlite3 操作sqlite 数据库
  4. cef谷歌内核浏览器获取cookie值并保存
  5. koa-mysql(三)
  6. LeetCode 1943. 描述绘画结果(差分思想)
  7. mysql实例怎么复制_Mysql实例MySQL数据库复制概论
  8. 三菱modbusRTU通讯实例_PLC编程入门梯形图实例讲解
  9. Brocade博科光纤交换机之 常用命令
  10. fineReport读取模板文件
  11. 如何批量给图片加水印?
  12. 时间序列pandas的创建date_range+时间戳的序列化to_datetime+重采样resample+将字符串时间转化为时间序列PeriodIndex(传入年月日)
  13. mybatis当传入数据类型为Int时并且值为0时,会判断为空字符串
  14. 程序员戴耳机是为了撩妹子?感觉好酷的样子~
  15. mysql随机生成名字,起名不求人
  16. JS 事件代理和事件委托
  17. 压缩视频大小画质不变,视频压缩大小清晰度不变怎么做?
  18. 加强版RFM模型,轻松扒出B站优质up主!
  19. [数据结构]二叉树的结构及实现
  20. 什么是CRC和CRC检验?

热门文章

  1. mysql流程控制_Mysql之流程控制结构
  2. 问题 B: 数塔问题
  3. 编程中的一种特殊递归-尾递归
  4. [剑指offer]面试题10:二进制中1的个数
  5. DevC++如何安装自定义头文件并使用
  6. [蓝桥杯2015初赛]手链样式-思维+next_permutation枚举(好题)
  7. 偷用计算机作文,偷玩电脑作文500字
  8. word List 42
  9. mingw w64 matlab,Matlab安装MinGW-w64问题解决
  10. min_25 推导及例题总结