概率论太难了,不会。但这不能阻止我们过题。
相信大家都会一个基于背包的暴力做法,我们可以将其看成是卷积的形式就可以用fft优化了。形式化讲,就是求幂级数$ (\sum\limits_{i = 0}^{x - 1} \frac{1}{x} z^i)^y $在$[z^A, z^B]$之间的系数和。

不在模意义下的做法
直接将上述幂级数暴力倍增卷积求出来复杂度是$O(x*y*log(xy))$,不太能过的。但如果不在模意义下做我们就可以尝试爆精度爆过去。很容易发现最后求得的点数和很大概率就是在均值附近的,过大过小的概率几乎为0。也就是我们中间在做卷积和有很多项几乎为0,我们把他们忽略掉是在精度的承受范围之内的。于是我们在做倍增求出上述幂级数的时候我们可以每次只保留中间的一小段有值的部分,其余的扔掉就行了。也就是说我们设定一个阈值$\epsilon$,每次卷积后把多项式中值$\le \epsilon$的都扔掉。这样复杂度就是$O(len*log(len + y))$,其中$len$是最终幂级数中值$> \epsilon$的个数。实践证明,当$\epsilon$取$10^{-9}$时,$len$大概是两三万,并且此时的精度可以达到小数点后4位。

在模意义下的做法
如果答案可以对某个质数取模,这题就更好做了。
考虑最开始的那个幂级数:

$(\sum\limits_{i = 0}^{x - 1} \frac{1}{x} z^i)^y = (\frac{1}{x} \frac{1 - z^x}{1 - z})^y = (\frac{1}{x})^y (1 - z^x)^y(\frac{1}{1 - z})^y$

我们想要求其在第$[A, B]$之间的系数和,我们可以乘上一个$\frac{1}{1 - x}$来做一次前缀和,这样我们可以转化成两次形如求一个$z^n$的系数的问题。也就是:

$[z^n] (\frac{1}{x})^y (1 - z^x)^y(\frac{1}{1 - z})^{y + 1}$

手动展开后面的两个:

$=[z^n] (\frac{1}{x})^y(\sum\limits_{i = 0}^{y}\binom{y}{i}(-1)^iz^{ix})(\sum\limits_{i = 0}\binom{y + i}{y}z^i)$

$=(\frac{1}{x})^y\sum\limits_{i = 0}^{y}\binom{y}{i}(-1)^i\binom{y + n - ix}{y}$

预处理组和数之后随便做一下就好了,复杂度$O(x*y)$。

$\bigodot$套路与技巧:

  • 隔板法用于展开形如$(\frac{1}{1 - z})^y$的幂级数。

做法一:

#include <bits/stdc++.h>

using namespace std;

namespace PO {
const int N = 4e5 + ;
const double PI = acos(-); struct Com {
double x, y;
friend Com operator + (Com a, Com b) {
return (Com){ a.x + b.x, a.y + b.y };
}
friend Com operator - (Com a, Com b) {
return (Com){ a.x - b.x, a.y - b.y };
}
friend Com operator * (Com a, Com b) {
return (Com){ a.x * b.x - a.y * b.y, a.x * b.y + a.y * b.x };
}
} ta[N], tb[N], w[N];
int rev[N], L = ;
typedef vector<Com> Poly; void Init(int l) {
for (; L < l; L <<= ) {
for (int i = L; i < (L << ); ++i) {
w[i] = (Com){ cos(PI / L * (i - L)), sin(PI / L * (i - L)) };
}
}
for (int i = ; i < l; ++i) {
rev[i] = (rev[i >> ] >> ) | (i & ? l >> : );
}
} void Dft(Com *a, int l) {
for (int i = ; i < l; ++i)
if (i < rev[i]) swap(a[i], a[rev[i]]);
for (int i = ; i < l; i <<= ) {
for (int j = ; j < l; j += i << ) {
Com *l = a + j, *r = l + i, *wx = w + i, y;
for (int k = ; k < i; ++k, ++l, ++r, ++wx) {
y = (*r) * (*wx);
*r = (*l) - y;
*l = (*l) + y;
}
}
}
}
void Idft(Com *a, int l) {
reverse(a + , a + l);
Dft(a, l);
for (int i = ; i < l; ++i) {
a[i].x /= l;
a[i].y /= l;
}
} vector<double> Mul(vector<double> a, vector<double> b) {
int n = a.size(), m = b.size(), l;
for (l = ; l < n + m - ; l <<= );
Init(l);
a.resize(l), b.resize(l);
for (int i = ; i < l; ++i) {
ta[i] = (Com){ a[i], };
tb[i] = (Com){ b[i], };
}
Dft(ta, l), Dft(tb, l);
for (int i = ; i < l; ++i) {
ta[i] = ta[i] * tb[i];
}
Idft(ta, l);
for (int i = ; i < l; ++i) {
a[i] = ta[i].x;
}
a.resize(n + m - );
return a;
} } void Cut(vector<double> &a, int &base) {
const double GAMA = 1e-;
int id = ;
while (a[id] < GAMA) ++id;
for (int i = ; i + id < a.size(); ++i) {
a[i] = a[i + id];
}
while (a.back() < GAMA) {
a.pop_back();
}
base += id;
} int main() {
int tc;
for (cin >> tc; tc--; ) {
int x, y;
cin >> x >> y; vector<double> ans(x * y);
vector<double> F(x, 1.0 / x), G(, );
int base_f = , base_g = ;
for (int ex = y; ex; ex >>= ) {
if (ex & ) {
G = PO::Mul(G, F);
base_g += base_f;
Cut(G, base_g);
}
F = PO::Mul(F, F);
base_f *= ;
Cut(F, base_f);
}
for (int i = ; i < G.size(); ++i) {
ans[i + base_g] = G[i];
}
for (int i = ; i < x * y; ++i) {
ans[i] += ans[i - ];
} for (int cas = ; cas--; ) {
int l, r;
cin >> l >> r;
printf("%.12f\n", ans[r] - (l? ans[l - ] : ));
}
} return ;
}

【SDOI 2017】龙与地下城(组合)的更多相关文章

  1. SDOI 2017 Day1

    日期:2017-04-10 题解: 第一题: 题目大意:求fi(gcd(i,j))的乘积  i,j属于[1,1e6],数据组数1000组. 类别:套路题. 第二题:BZOJ原题. 题解:LCT套线段树 ...

  2. [SDOI 2017]新生舞会

    Description 题库链接 给你个 \(2\times N\) 的带权二分图,两个权值 \(a,b\) ,让你做匹配使得 \[\frac{\sum a}{\sum b}\] 最大. \(1\le ...

  3. [SDOI 2017]数字表格

    Description 题库链接 记 \(f_i\) 为 \(fibonacci\) 数列的第 \(i\) 项. 求 \[\prod_{i=1}^n\prod_{j=1}^mf_{gcd(i,j)}\ ...

  4. [BZOJ 4817] [SDOI 2017] 树点涂色

    Description Bob有一棵 \(n\) 个点的有根树,其中 \(1\) 号点是根节点.Bob在每个点上涂了颜色,并且每个点上的颜色不同. 定义一条路径的权值是:这条路径上的点(包括起点和终点 ...

  5. [BZOJ 4819] [SDOI 2017] 新生舞会

    Description 学校组织了一次新生舞会,Cathy作为经验丰富的老学姐,负责为同学们安排舞伴. 有 \(n\) 个男生和 \(n\) 个女生参加舞会买一个男生和一个女生一起跳舞,互为舞伴. C ...

  6. [BZOJ 4818] [SDOI 2017] 序列计数

    Description Alice想要得到一个长度为 \(n\) 的序列,序列中的数都是不超过 \(m\) 的正整数,而且这 \(n\) 个数的和是 \(p\) 的倍数. Alice还希望,这 \(n ...

  7. 解题:SDOI 2017 硬币游戏

    题面 板板的生成函数做法太神仙了,我跑了 朴素的做法是建立AC自动机变成图上的随机游走问题 来仔细考虑一下转移,把状态分成非结尾状态和结尾状态.在一个非结尾状态后补一个串是一定能到达目标串的,但是如果 ...

  8. BZOJ.4909.[SDOI2017]龙与地下城(正态分布 中心极限定理 FFT Simpson积分)

    BZOJ 洛谷 https://www.luogu.org/blog/ShadowassIIXVIIIIV/solution-p3779# 正态分布 正态分布是随机变量\(X\)的一种概率分布形式.它 ...

  9. SDOI 2017 天才黑客

    /* 根据claris的 博客以及 beginend 的博客来写的 首先考虑如何求出最短路 可以从样例看出 路径是从边走到边的, 所以我们将边看作点 有共同端点的两边之间 互相连边, 边权为lcp. ...

随机推荐

  1. Ubuntu 打包后安装提示:子进程 已安装 pre-removal 脚本 返回了错误号 1

    子进程 已安装 pre-removal 脚本 返回了错误号 1或2 与 子进程 已安装 post-installation 脚本 返回了错误号 1或2   一.子进程 已安装 pre-removal  ...

  2. copy constructor

    copy constructor也分为trivial和nontrivial两种 如果class展现出bitwise copy semantics(按位拷贝语义),则不会构造出 copy constru ...

  3. C#断点续传下载。

    断点续传 最近在优化之前的下载流程,仅此篇幅留作笔记之用,日后其他研究此类问题的伙伴可以马上了解原理和开发,减少开发成本. 原理:断点续传目前比较通用的是使用HTTP续传方式,相关的资料可以通过访问: ...

  4. vue-router 注意事项

    1.vue-router 两种模式 (1)mode:hash,hash模式背后的原理是onhashchange事件,可以在window对象上监听这个事件.vue默认为hash模式 window.onh ...

  5. 我的devops实践经验分享一二

    前言 随着系统越来越大,开发人员.站点.服务器越来越多,微服务化推进,......等等原因,实现自动化的devops越来越有必要. 当然,真实的原因是,在团队组建之初就预见到了这些问题,所以从一开始就 ...

  6. youtube下载工具

    Youtube是一个全球性的视频分享网站,其种类之多,内容之丰富,是大家有目共睹的.特别是原创视频更是多不胜数, 每分钟都有400+小时的youtube视频上传,每天都有30亿+的视频被观看.随着视频 ...

  7. [T-ARA][남주긴 아까워][给别人可惜了]

    歌词来源:http://music.163.com/#/song?id=29343992 作曲 : 二段横踢/Radio Galaxi [作曲 : 二段横踢/Radio Galaxi] 作词 : 二段 ...

  8. 《Linux内核设计与分析》第六周读书笔记——第三章

    <Linux内核设计与实现>第六周读书笔记——第三章 20135301张忻估算学习时间:共2.5小时读书:2.0代码:0作业:0博客:0.5实际学习时间:共3.0小时读书:2.0代码:0作 ...

  9. h5定位geolaction无法调试解决方法

    昨天接到一个在h5获取经纬度的需求,看了文档后,代码其实很简单,但在浏览器上调试就比较蛋疼了... 代码: function successfulCallback(position) { consol ...

  10. Hitchhiker 是一款开源的 Restful Api 测试工具

    Hitchhiker 是一款开源的 Restful Api 测试工具 开源API测试工具 Hitchhiker v0.4更新 - 没有做不到,只有想不到 Hitchhiker 是一款开源的 Restf ...