In Pavlopolis University where Noora studies it was decided to hold beauty contest "Miss Pavlopolis University". Let's describe the process of choosing the most beautiful girl in the university in more detail.
The contest is held in several stages. Suppose that exactly n girls participate in the competition initially. All the participants are divided into equal groups, x participants in each group. Furthermore the number x is chosen arbitrarily, i. e. on every stage number x can be different. Within each group the jury of the contest compares beauty of the girls in the format "each with each". In this way, if group consists of x girls, then comparisons occur. Then, from each group, the most beautiful participant is selected. Selected girls enter the next stage of the competition. Thus if n girls were divided into groups, x participants in each group, then exactly participants will enter the next stage. The contest continues until there is exactly one girl left who will be "Miss Pavlopolis University"
But for the jury this contest is a very tedious task. They would like to divide the girls into groups in each stage so that the total number of pairwise comparisons of the girls is as few as possible. Let f(n) be the minimal total number of comparisons that should be made to select the most beautiful participant, if we admit n girls to the first stage.
The organizers of the competition are insane. They give Noora three integers t, l and r and ask the poor girl to calculate the value of the following expression: t0·f(l) + t1·f(l + 1) + ... + tr - l·f(r). However, since the value of this expression can be quite large the organizers ask her to calculate it modulo 109 + 7. If Noora can calculate the value of this expression the organizers promise her to help during the beauty contest. But the poor girl is not strong in mathematics, so she turned for help to Leha and he turned to you.
The first and single line contains three integers t, l and r (1 ≤ t < 109 + 7, 2 ≤ l ≤ r ≤ 5·106).
In the first line print single integer — the value of the expression modulo 109 + 7.
2 2 4
19
Consider the sample.
It is necessary to find the value of .
f(2) = 1. From two girls you can form only one group of two people, in which there will be one comparison.
f(3) = 3. From three girls you can form only one group of three people, in which there will be three comparisons.
f(4) = 3. From four girls you can form two groups of two girls each. Then at the first stage there will be two comparisons, one in each of the two groups. In the second stage there will be two girls and there will be one comparison between them. Total 2 + 1 = 3 comparisons. You can also leave all girls in same group in the first stage. Then comparisons will occur. Obviously, it's better to split girls into groups in the first way.
Then the value of the expression is .
题目大意 某个学校要开展神奇的选美大赛,然后首先将n个女孩分成x组(x自定,且为n的约数),然后每一组中两两进行比较选出最漂亮的一位参加下一轮选拔。最终剩下的1人是冠军。定义f(n)表示在n个女孩中,选出最漂亮的一位最少需要的比较次数。求。
看到l和r的范围是5e6,大概可以猜到快速预处理出f(i)然后暴力求和。而且看到AC这道题的人数有1000多人,也就是说不太可能是莫比乌斯反演之类的神数论方法。
关键在于如何快速预处理出f(i)。
首先写出f(n)的定义式(用数学语言去代替文字语言,某种程度上简化了问题)(d不等于1)。
再看看数据范围,是不是觉得该用线性筛啊?好,那一定和最小的质因子脱不了干系。然后再举几个数据。
于是我们再根据数学的直觉和人生的哲理得到当n是合数(素数的时候只有一种转移,可以直接算),每组人数是n的最小质因子的时候最优。(说白了,我就是猜的。但是说实话,比赛的时候确实需要一些直觉。。对于像我这种蒟蒻,如果比赛时花半天耗在证明上,万一证出来没时间写,多亏,还不如骗骗分,得一分算一分,WA再猜,再推。比赛结束了慢慢证明)
由于想了半天,没有想出来,就打上Lazy标记吧,回去问问学长们。
为了简化计算,所以证明一下。
然后来证明一下,在转移的时候,合数没有素数优秀。
设,假设,那么现在需要找多一组合法的转移使得转以后的函数值比这个小。但是很不辛的是,我们可以证明当
会比它优秀一些。由于f(x)都一样,现在来证明前一个的后面那一坨比后一个后面那一坨大。
(这一段感谢codeforecs题解,如果没看懂,可以自己去看原文)
现在我们希望证明,当d1和d2都是素数的时候,且d1 < d2,那么当f(x)先通过d2再通过d1转移到f(n)比先通过d1再通过d2转移更优秀(意思说如果d不是n的最小质因子,那么我就可以构造出一组转移把它更优秀)。这次我们使用作差法。
因为,所以最终的式子的正负性只和有关,因为d1,d2都大于1,所以有。所以。
因此若n的最小质因子为d,则f(n)通过f(n / d)比其它任何质因子p,f(n)通过f(n / p)都要优秀。
(这一段是我自己证的,有问题请一定指出来,由于我跳了比较多的步骤,所以如果没有看懂,请在评论区提出疑问。)
Code
/**
* Codeforces
* Problem#882D
* Accepted
* Time: 202ms
* Memory: 29300k
*/
#include <bits/stdc++.h>
using namespace std;
typedef bool boolean; const int moder = 1e9 + ; int t, l, r; inline void init() {
scanf("%d%d%d", &t, &l, &r);
} int num = ;
int prime[];
boolean vis[];
int *f;
inline int C2(int n) { return (n * 1LL * (n - ) / ) % moder; }
inline void Euler() {
f = new int[(r + )];
memset(vis, , sizeof(boolean) * (r + ));
f[] = ;
for(int i = ; i <= r; i++) {
if(!vis[i]) prime[num++] = i, f[i] = C2(i);
for(int j = ; j < num && i * prime[j] <= r; j++) {
int c = i * prime[j];
vis[c] = true;
f[c] = (f[i] + (f[prime[j]] * 1LL * i) % moder) % moder;
if((i % prime[j]) == ) break;
}
}
// for(int i = 1; i <= r; i++)
// cout << f[i] << " ";
// cout << endl;
} int res = ;
inline void solve() {
int t0 = ;
for(int i = l; i <= r; i++, t0 = (t0 * 1LL * t) % moder) {
res = (res + t0 * 1LL * f[i]) % moder;
}
printf("%d\n", res);
} int main() {
init();
Euler();
solve();
return ;
}
更新日志
- 2017-8-2 21:30 补上证明