【组合数学】【P5216】DLS采花
Description
DLS 有 \(N\) 个花田,每个花田里有 \(a_i\) 朵花。
DLS 喜欢稀奇古怪的花田,他希望重新排列花田,然后去采花。
但 DLS 采花又有一个癖好:他会从左往右采花。
若当前采到第 \(i\) 个花田,在之前有一个花田的花的数量,是第 \(i\) 个花田的花的数量的因子的话,那么 DLS 不会采这个花田的花。
现在,DLS 想知道对于所有排列花田的方案,他能够采到的花的数量的和是多少。
由于答案会比较大,请对 \(998244353\) 取模。
Input
第一行是一个整数 \(N\)
下面一行 \(N\) 个整数代表这个序列
Output
输出答案对 \(998244353\) 取膜的结果
Hint
\(for~50~percents:N~\leq~9\)
\(for~80~percent:N~\leq~1000\)
\(forall:1~\leq~N~\leq~10^5,1~\leq~10^5\)
Solution
感觉所有的题解都没有写部分分和式子是怎么用数学方法推出来的啊qwq
考虑前50分,直接枚举全排列检验,时间复杂度 \(O(n!~\times~n^2)\),期望得分50pts。
考虑前80的数据,我们发现问题等价于求\(\sum_{i = 1}^n a_i ~ \times~\text{序列中所有}a_i\text{的因数都在}a_i\text{的后面的方案数}\)。问题转化为如何求出方案数。
对于每个 \(a_i\),我们考虑枚举他在产生贡献方案中的位置。设 \(a_i\) 除去他自身共有 \(k\) 个因数在序列中。
当 \(a_i\) 放在倒数第 \(k + 1\) 位置上时,后面 \(k\) 个因数随便放,前面的所有数字随便放,所以方案数为 \(k!~\times~(n - k - 1)!\)
当 \(a_i\) 放在倒数第 \(k + 2\) 位置上时,后面 \(k\) 个因数和随便一个非因数随便放,前面剩下的数字随便放。由于非因数是随便选的,所以方案数为 \((k + 1)!~\times~(n - k - 2)!~\times~C_{n - k - 1}^{1}\)
当 \(a_i\) 放在倒数第 \(k + 3\) 位置上时,后面 \(k\) 个因数和随便两个非因数随便放,前面剩下的数字随便放。由于非因数是随便选的,所以方案数为 \((k + 2)!~\times~(n - k - 3)!~\times~C_{n - k - 1}^{2}\)
一位读者砸烂了复读机停止了复读
依此做数学归纳,可得答案即为
\]
相当于枚举 \(a_i\) 在倒数第 \(i + 1\) 位时的答案。
发现这个式子sigma后面可以在预处理阶乘和逆元后 \(O(1)\) 计算,整个sigma可以 \(O(n)\) 计算,一共算 \(n\) 次,于是总复杂度 \(O(n^2)\),期望得分80pts。
考虑全部的数据,我们发现上面先枚举 \(a_i\) 的位置再枚举因数怎么放的多余的,可以直接把他们放在一起枚举:我们在一个序列中选择 \((k + 1)\) 个位置,其中第一个位置放 \(a_i\),其他位置放因数,剩下的位置随便放,于是答案即为
\]
这个式子在预处理后可以 \(O(1)\) 计算,于是算上求因数后总复杂度 \(O(n~\sqrt a)\),期望得分100pts。
Code
#include <cstdio>
#ifdef ONLINE_JUDGE
#define freopen(a, b, c)
#define printtime()
#else
#include <ctime>
#define printtime() printf("Times used = %ld ms\n", clock())
#endif
#define ci const int
#define cl const long long
typedef long long int ll;
namespace IPT {
const int L = 1000000;
char buf[L], *front=buf, *end=buf;
char GetChar() {
if (front == end) {
end = buf + fread(front = buf, 1, L, stdin);
if (front == end) return -1;
}
return *(front++);
}
}
template <typename T>
inline void qr(T &x) {
char ch = IPT::GetChar(), lst = ' ';
while ((ch > '9') || (ch < '0')) lst = ch, ch=IPT::GetChar();
while ((ch >= '0') && (ch <= '9')) x = (x << 1) + (x << 3) + (ch ^ 48), ch = IPT::GetChar();
if (lst == '-') x = -x;
}
namespace OPT {
char buf[120];
}
template <typename T>
inline void qw(T x, const char aft, const bool pt) {
if (x < 0) {x = -x, putchar('-');}
int top=0;
do {OPT::buf[++top] = static_cast<char>(x % 10 + '0');} while (x /= 10);
while (top) putchar(OPT::buf[top--]);
if (pt) putchar(aft);
}
const int maxn = 100010;
const int MOD = 998244353;
int n;
int MU[maxn], bk[maxn];
ll ans;
ll fact[maxn], inv[maxn], finv[maxn];
ll C(int, int);
int main() {
freopen("1.in", "r", stdin);
qr(n);
for (int i = 1; i <= n; ++i) {
qr(MU[i]); ++bk[MU[i]];
}
fact[0] = finv[0] = inv[1] = 1;
for (int i = 2; i <= n; ++i) inv[i] = (MOD - MOD / i) * inv[MOD % i] % MOD;
for (int i = 1; i <= n; ++i) fact[i] = fact[i - 1] * i % MOD, finv[i] = finv[i - 1] * inv[i] % MOD;
for (int i = 1; i <= n; ++i) {
int _cnt = 0;
int j;
for (j = 1; (j * j) < MU[i]; ++j) if (!(MU[i] % j)) _cnt += bk[j] + bk[MU[i] / j];
if ((j * j) == MU[i]) _cnt += bk[j];
--_cnt;
ans = (ans + C(n, _cnt + 1) * fact[_cnt] % MOD * fact[n - _cnt - 1] % MOD * MU[i]) % MOD;
}
qw((ans + MOD) % MOD, '\n', true);
printtime();
}
ll C(int x, int y) {
return fact[x] * finv[y] % MOD * finv[x - y] % MOD;
}
【组合数学】【P5216】DLS采花的更多相关文章
- [洛谷P5216]DLS 采花
题目大意:有$n$个数,任意排列,排列后第$i$个数会产生贡献当且仅当$1\sim i-1$中的数不是它的因子,问所有排列的贡献和 题解:发现一个数要产生贡献要求所有它的因子在它的右边,设有$cnt_ ...
- BZOJ 2743 【HEOI2012】 采花
题目链接:采花 这道题一眼看去,一个很显然的想法就是莫队.但是数据范围是\(10^6\)级别的,莫队显然已经过不去了. 其实感觉这道题和以前写过的一道题HH的项链很像.只不过那道题要求的是区间出现次数 ...
- 【HEOI2012】采花 BZOJ2743
Description 萧芸斓是Z国的公主,平时的一大爱好是采花. 今天天气晴朗,阳光明媚,公主清晨便去了皇宫中新建的花园采花.花园足够大,容纳了n朵花,花有c种颜色(用整数1-c表示),且花是排成一 ...
- 采花 bzoj 2743
采花(1s 128MB)flower [题目描述] 萧芸斓是Z国的公主,平时的一大爱好是采花. 今天天气晴朗,阳光明媚,公主清晨便去了皇宫中新建的花园采花.花园足够大,容纳了n朵花,花有c种颜色(用整 ...
- BZOJ 2743: [HEOI2012]采花
2743: [HEOI2012]采花 Time Limit: 15 Sec Memory Limit: 128 MBSubmit: 2056 Solved: 1059[Submit][Status ...
- [bzoj2743][HEOI2012]采花(树状数组+离线)
2743: [HEOI2012]采花 Time Limit: 15 Sec Memory Limit: 128 MBSubmit: 1832 Solved: 954[Submit][Status] ...
- cdoj 1489 老司机采花
地址:http://acm.uestc.edu.cn/#/problem/show/1489 题目: 老司机采花 Time Limit: 3000/1000MS (Java/Others) M ...
- 数据结构(树状数组):HEOI2012 采花
[题目描述] 萧薰儿是古国的公主,平时的一大爱好是采花. 今天天气晴朗,阳光明媚,公主清晨便去了皇宫中新建的花园采花.花园足够大,容纳了n朵花,花有c种颜色(用整数1-c表示),且花是排成一排的,以便 ...
- BZOJ 2743: [HEOI2012]采花( 离线 + BIT )
处理出每个数下一个出现的位置, 然后按左端点排序回答询问.处理当前数去除的影响 ------------------------------------------------------------ ...
随机推荐
- Notes of Scrum Meeting(2014/11/2)
Notes of Scrum Meeting (2014/11/2) 软件工程项目组Sevens开始项目之后的第一次Scrum Meeting报告 会议时间:2014年11月2日 20:00—20: ...
- 优化Hibernate所鼓励的7大措施:
优化Hibernate所鼓励的7大措施: 1.尽量使用many-to-one,避免使用单项one-to-many 2.灵活使用单向one-to-many 3.不用一对一,使用多对一代替一对一 4.配置 ...
- Java& Vector与ArrayList区别
在写java的时候,基本上都喜欢用arraylist,甚至我都不知道有个vector的存在.查了一下发现又是线程安全问题...咋个线程安全天天围着我转呢...多得阿里巴巴,让我开始认识java的所谓线 ...
- BeTa阶段Day4
一.提供当天站立式会议照片一张 二.每个人的工作 1.讨论项目每个成员的昨天进展 刘阳航:优化障碍物生成. 林庭亦:调整难度设置. 郑子熙:改进UI,美化界面. 陈文俊:优化代码结构. 2.讨论项目每 ...
- beta 发布的相关评论
1. 礼物挑选小工具 飞天小女警 这个项目的创意独具匠心,贴近实际,令人耳目一新,网站的页面也是玫红色的,配色让人感到很温馨,对礼物的筛选方式很有趣,使用的记录特殊日子的方法来提醒自己挑选礼 ...
- SQL Server:获取本月最后一天[转]
方法一:set @EndDate = dateadd(month, datediff(month, -1, @StoredDate), -1) @StoredDate为本月的任意一天 这里datedi ...
- 通过ctrl+r快速启动程序
步骤1:在[我的电脑]右键-[系统属性]-[环境变量]中增加如图1设置并保存 步骤2:在图2中添加步骤1中增加的变量名并保存 步骤3:在ctrl+r的运行窗口中输入步骤1中的变量名即可快速启动程序 ...
- 无法安装HAXM (VT-X is not turned on)
安装HAXM的时候,VT-X is not turned on. 进入bios查看,已经启动了vt-x.上网搜索发现解决有一部分电脑是因为安装了Hyper-V,解决的方法: 管理员运行cmd,输入如下 ...
- mysql索引利弊分析
转载自:http://blog.csdn.net/linminqin/article/details/44342205 索引的利弊与如何判定,是否需要索引 相信读者都知道索引能够极大地提高数据检索的 ...
- BugScan插件编写高(gǎo)级(jī)教程
声明:本文最先发布在:http://q.bugscan.net/t/353 转载请注明出处 有问题可以和我交流 邮件(Medici.Yan@gmail.com) 个人博客地址:http://www.c ...