P4562 [JXOI2018]游戏
题面
题目描述
她长大以后创业了,开了一个公司。 但是管理公司是一个很累人的活,员工们经常背着可怜偷懒,可怜需要时不时对办公室进行检查。
可怜公司有 \(n\) 个办公室,办公室编号是 \(l\) 到 \(l+n-1\) ,可怜会事先制定一个顺序,按照这个顺序依次检查办公室。一开始的时候,所有办公室的员工都在偷懒,当她检查完编号是 \(i\) 的办公室时候,这个办公室的员工会认真工作,并且这个办公室的员工通知所有办公室编号是 \(i\) 的倍数的办公室,通知他们老板来了,让他们认真工作。因此,可怜检查完第 \(i\) 个办公室的时候,所有编号是 \(i\) 的倍数(包括 \(i\) )的办公室的员工会认真工作。
可怜发现了员工们通风报信的行为,她发现,对于每种不同的顺序 \(p\) ,都存在一个最小的 \(t(p)\) ,使得可怜按照这个顺序检查完前 \(t(p)\) 个办公室之后,所有的办公室都会开始认真工作。她把这个 \(t(p)\) 定义为 \(p\) 的检查时间。
可怜想知道所有 \(t(p)\) 的和。
但是这个结果可能很大,她想知道和对 \(10^9+7\) 取模后的结果。
输入格式:
第一行输入两个整数 \(l\) , \(r\) 表示编号范围,题目中的 \(n\) 就是 \(r-l+1\) 。
输出格式:
一个整数,表示期望进行的轮数。
输入输出样例
输入样例#1:
2 4
输出样例#1:
16
\(\text{Solution:}\)
考虑到一个数能对答案有贡献,那么它一定不是其它数的倍数,假设这样的数有sum个。
对于九条可怜任意选择的排列,那么答案就是排列中最靠后的不能被其它数表示出来的数的位置。
所以我们可以枚举最靠后的那个数的位置 \(i\) ,\(i\) 位置可以选择 \(sum\) 个数中的任何一个数,而对于 \(i\) 后面的数它们是从 \(n-sum\) 个数中选出的 \(n-i\) 个数,而且可以随意排列,\(i\) 之前的数也可以随意排列,所以我们就有了一个用一堆乘法原理推出来的式子:
Ans=\sum_{i=sum}^{n}i \times sum \times C_{n-sum}^{n-i} \times (n-i)! \times (i-1)!
\end{aligned}
\]
#include <set>
#include <cmath>
#include <cctype>
#include <cstdio>
#include <cstring>
#include <iostream>
#include <assert.h>
#include <algorithm>
using namespace std;
#define fir first
#define sec second
#define pb push_back
#define mp make_pair
#define LL long long
#define INF (0x3f3f3f3f)
#define mem(a, b) memset(a, b, sizeof (a))
#define debug(...) fprintf(stderr, __VA_ARGS__)
#define Debug(x) cout << #x << " = " << x << endl
#define travle(i, x) for (register int i = head[x]; i; i = nxt[i])
#define For(i, a, b) for (register int (i) = (a); (i) <= (b); ++ (i))
#define Forr(i, a, b) for (register int (i) = (a); (i) >= (b); -- (i))
#define file(s) freopen(s".in", "r", stdin), freopen(s".out", "w", stdout)
#define ____ debug("go\n")
namespace io {
static char buf[1<<21], *pos = buf, *end = buf;
inline char getc()
{ return pos == end && (end = (pos = buf) + fread(buf, 1, 1<<21, stdin), pos == end) ? EOF : *pos ++; }
inline int rint() {
register int x = 0, f = 1;register char c;
while (!isdigit(c = getc())) if (c == '-') f = -1;
while (x = (x << 1) + (x << 3) + (c ^ 48), isdigit(c = getc()));
return x * f;
}
inline LL rLL() {
register LL x = 0, f = 1; register char c;
while (!isdigit(c = getc())) if (c == '-') f = -1;
while (x = (x << 1ll) + (x << 3ll) + (c ^ 48), isdigit(c = getc()));
return x * f;
}
inline void rstr(char *str) {
while (isspace(*str = getc()));
while (!isspace(*++str = getc()))
if (*str == EOF) break;
*str = '\0';
}
template<typename T>
inline bool chkmin(T &x, T y) { return x > y ? (x = y, 1) : 0; }
template<typename T>
inline bool chkmax(T &x, T y) { return x < y ? (x = y, 1) : 0; }
}
using namespace io;
const int N = 1e7 + 10, P = 1e9 + 7;
int fac[N], ifac[N];
int qpow(int a, int b)
{
int res = 1;
while (b)
{
if (b & 1) res = 1ll * a * res % P;
a = 1ll * a * a % P;
b >>= 1;
}
return res;
}
void init(int n)
{
fac[0] = 1;
for (int i = 1; i <= n; ++ i)
fac[i] = 1ll * fac[i - 1] * i % P;
ifac[n] = qpow(fac[n], P - 2);
for (int i = n - 1; i >= 0; -- i)
ifac[i] = 1ll * ifac[i + 1] * (i + 1) % P;
}
int C(int n, int m)
{
if (n < m) return 0;
return 1ll * fac[n] % P * 1ll * ifac[m] % P * 1ll * ifac[n - m] % P;
}
bool vis[N];
int main() {
#ifndef ONLINE_JUDGE
file("P4562");
#endif
int n, L, R, sum = 0;
cin >> L >> R;
n = R - L + 1;
init(R);
for (int i = L; i <= R; ++ i)
{
if (!vis[i]) sum++;
for (int j = i + i; j <= R; j += i)
vis[j] = true;
}
int ans = 0;
for (int i = sum; i <= n; ++ i)
ans = (ans + 1ll * i * fac[i - 1] % P * sum % P * C(n - sum, n - i) % P * fac[n - i] % P) % P;
cout << ans << endl;
}
P4562 [JXOI2018]游戏的更多相关文章
- luogu P4562 [JXOI2018]游戏 组合数学
LINK:游戏 当L==1的时候 容易想到 答案和1的位置有关. 枚举1的位置 那么剩下的方案为(R-1)! 那么总答案为 (R+1)*R/2(R-1)! 考虑L==2的时候 对于一个排列什么时候会终 ...
- 洛谷P4562 [JXOI2018]游戏(组合数学)
题意 题目链接 Sol 这个题就比较休闲了. \(t(p)\)显然等于最后一个没有约数的数的位置,那么我们可以去枚举一下. 设没有约数的数的个数有\(cnt\)个 因此总的方案为\(\sum_{i=c ...
- 洛谷P4562 [JXOI2018]游戏 数论
正解:数论 解题报告: 传送门! 首先考虑怎么样的数可能出现在t(i)那个位置上?显然是[l,r]中所有无法被表示出来的数(就约数不在[l,r]内的数嘛QwQ 所以可以先把这些数筛出来 具体怎么筛的话 ...
- Luogu P4562 [JXOI2018]游戏
题目 我们用埃氏筛从\(l,r\)筛一遍,每次把没有被筛掉的数的倍数筛掉. 易知最后剩下来的数(这个集合记为\(S\))的个数就是我们需要选的数,设有\(s\)个,令\(n=r-l+1\). 记\(f ...
- 【BZOJ5323】[JXOI2018]游戏(组合计数,线性筛)
[BZOJ5323][JXOI2018]游戏(组合计数,线性筛) 题面 BZOJ 洛谷 题解 显然要考虑的位置只有那些在\([l,r]\)中不存在任意一个约数的数. 假设这样的数有\(x\)个,那么剩 ...
- [JXOI2018]游戏 (线性筛,数论)
[JXOI2018]游戏 \(solution:\) 这一道题的原版题面实在太负能量了,所以用了修改版题面. 这道题只要仔细读题,我们就可以将题目的一些基本性质分析出来:首先我们定义:对于某一类都可以 ...
- 【题解】JXOI2018游戏(组合数)
[题解]JXOI2018游戏(组合数) 题目大意 对于\([l,r]\)中的数,你有一种操作,就是删除一个数及其所有倍数.问你删除所有数的所有方案的步数之和. 由于这里是简化题意,有一个东西没有提到: ...
- BZOJ5323 & 洛谷4562:[JXOI2018]游戏——题解
https://www.luogu.org/problemnew/show/P4562 https://www.lydsy.com/JudgeOnline/problem.php?id=5323 (B ...
- [JXOI2018]游戏
嘟嘟嘟 九条可怜竟然有这种良心题,似乎稍稍刷新了我对九条可怜的认识. 首先假设我们求出了所有必须要筛出来的数m,那么\(t(p)\)就只受最后一个数的位置影响. 所以我们枚举最后一个数的位置,然后用组 ...
随机推荐
- Python学习之路 (一)开发环境搭建
前言 python3应该是Python的趋势所在,当然目前争议也比较大,这篇随笔的主要目的是记录在centos6.7下搭建python3环境的过程 以及碰到的问题和解决过程. 另外,如果本机安装了py ...
- DOS命令行简单用法
DOS命令行简单用法 基本用法 1.cd(回车)从当前目录切回到根目录. 2.dir(回车)列出当前目录下的所有文件. 3.md kkk(回车)在当前目录下创建一个名称为kkk的文件夹. 4.rd k ...
- 集合之HashTable
在java中与有两个类都提供了一个多种用途的hashTable机制,他们都可以将可以key和value结合起来构成键值对通过put(key,value)方法保存起来,然后通过get(key)方法获取相 ...
- Google 地图切片URL地址解析
一.Google地图切片的投影方式及瓦片索引机制 1.地图投影 Google地图采用的是Web墨卡托投影(如下图),为了方便忽略了两极变形较大的地区,把世界地图做成了一个边长等于赤道周长的正方形(赤道 ...
- java集合---迭代器iterator
一:ArraryList 最终继承超级接口Collection,Colection接口继承Iterator接口. public interface Collection<E> exten ...
- Python学习笔记系列——数据结构相关
Python有4种数据结构:列表(list).字典(dictionary).元组(Tuple).集合(set).从最直接的感官上来说,这四种数据结构的区别是:列表中的元素使用方括号括起来,字典和集合是 ...
- 【转载】Caffe + Ubuntu 14.04 + CUDA 6.5 新手安装配置指南
洋洋洒洒一大篇,就没截图了,这几天一直在折腾这个东西,实在没办法,不想用Linux但是,为了Caffe,只能如此了,安装这些东西,遇到很多问题,每个问题都要折磨很久,大概第一次就是这样的.想想,之后应 ...
- 通过ReentrantLock简单了解下并发包中的锁
ReentrantLock在进行实例化时,可以通过构造函数的参数选择是否使用公平锁FairSync或者非公平锁NonfairSync,两者的区别比较简单,如果是公平锁则新来的线程会先检测同步队列中是否 ...
- Altium Ddesigner 栅格 含义
栅格分为可视栅格(Visible Grid).捕获栅格(snap grid).元件放置捕获栅格(Component Grid).电气栅格(Electrical Grid). 可视栅格:就是编辑过程中看 ...
- 用margin实现两列布局中的自适应列
<div id="wrapper"> <div id="col1"> "fixed" </div> &l ...