[数学] 挑战nbc
题目描述
A b w a d Abwad Abwad 是一名有志向的优秀 OI 少年。遗憾的是,由于高能宇宙射线的影响,他不幸在 NOI 中滚粗。不过, A b w a d Abwad Abwad 才高一,还有许许多多的机会。在长时间的刻苦学习之后,他实力大增,并企图撼动 OI 界魔王 n b c nbc nbc 的权威。 这一天, A b w a d Abwad Abwad 决定挑战 n b c nbc nbc。挑战的项目是 OI 界一种常见的运动:造题,比的就是谁造得又快又好。 A b w a d Abwad Abwad 现在拿到了难度为 1 , 2 , 3 , … … n 1,2,3,……n 1,2,3,……n 的 n n n 道原题,每次操作他可以挑出任意两道题,并使用一种叫做 NOIP二合一
的方法合成一道难度为其平均值的题。 A b w a d Abwad Abwad 希望在操作了 n − 1 n-1 n−1 次之后,最后剩下的那道题难度最大。
输入格式
输入仅一行一个整数,表示 n n n。
输出格式
输出一行仅一个整数 a n s ans ans,若答案的最简分数为 x / y x / y x/y, a n s ans ans 应为最小的满足 a n s × y m o d 1000000007 = x ans \times y \bmod 1000000007 = x ans×ymod1000000007=x 的整数。(其实就是分数取模辣)
样例
样例输入1:
2
样例输出1:
500000005
样例1解释:
显然答案为 3 / 2 3/2 3/2, 500000005 × 2 m o d 1000000007 = 3 500000005 \times 2 \bmod 1000000007 = 3 500000005×2mod1000000007=3。
数据范围
测试点编号 | n n n |
---|---|
1 1 1 | n ≤ 3 n \le 3 n≤3 |
2 2 2 | n ≤ 5 n \le 5 n≤5 |
3 3 3 | n ≤ 10 n \le 10 n≤10 |
4 , 5 4,5 4,5 | n ≤ 100 n \le 100 n≤100 |
6 , 7 , 8 6,7,8 6,7,8 | n ≤ 100000 n \le 100000 n≤100000 |
9 , 10 9, 10 9,10 | n ≤ 1 0 9 n \le 10^9 n≤109 |
提示
可能用到的知识:
费马小定理:当 p p p 是质数时, a p − 1 m o d p = 1 a^{p - 1} \bmod p = 1 ap−1modp=1。
题解
前置知识:分数取模。
若 t t t 为质数且 x × p m o d t = q x \times p \bmod t = q x×pmodt=q,则 x = q × p t − 2 m o d t x = q \times p^{t - 2} \bmod t x=q×pt−2modt。
我们来推导一下。
由费马小定理可知, p t − 1 m o d t = 1 p^{t - 1} \bmod t = 1 pt−1modt=1,原式两边乘上 p t − 2 p^{t - 2} pt−2,得到 x = q × p t − 2 m o d t x = q \times p^{t - 2} \bmod t x=q×pt−2modt。
所以我们就推完了。
显然, 1 1 1 到 n n n 应该按顺序合并。
假设有三个数 a , b , c a ,b, c a,b,c,先合并 a , b a,b a,b,再合并 c c c,生成的数为 ( ( a + b ) / 2 + c ) / 2 = a / 4 + b / 4 + c / 2 ((a+b)/2+c)/2=a/4+b/4+c/2 ((a+b)/2+c)/2=a/4+b/4+c/2。当然是让 c c c 更大,合并出来的数就越大。
由于最后算的不是合并的数,而是分数取模,所以先把式子写出来: a 1 / 2 n − 1 + a 2 / 2 n − 1 + a 3 / 2 + … … + a n / 2 a_1 / 2^{n-1} + a_2 / 2^{n-1} + a_3 / 2^{} + …… + a_n / 2 a1/2n−1+a2/2n−1+a3/2+……+an/2。通分后分母是 2 n − 1 2^{n - 1} 2n−1,分子是 1 + 2 + 2 × 3 + 4 × 4 + 8 × 5 + … + 2 n − 1 × n 1 + 2 + 2 \times 3 + 4 \times 4 + 8 \times 5 + \ldots + 2^{n - 1} \times n 1+2+2×3+4×4+8×5+…+2n−1×n。
此时如果直接写 O ( n ) O(n) O(n) 的暴力就有 80 80 80 分。
考虑进行优化。
观察分子: 1 + 2 + 2 × 3 + 4 × 4 + 8 × 5 + … + 2 n − 2 × n 1 + 2 + 2 \times 3 + 4 \times 4 + 8 \times 5 + \ldots + 2^{n - 2} \times n 1+2+2×3+4×4+8×5+…+2n−2×n。
1 , 2 , 4 , … , 2 n − 2 1,2,4,\ldots,2^{n - 2} 1,2,4,…,2n−2,显然是一个等比数列,值为 2 × 2 n − 2 − 1 = 2 n − 1 − 1 2\times 2^{n - 2} - 1 = 2^{n-1} - 1 2×2n−2−1=2n−1−1。
接下来的是我的考场做法。
把分子拆分开来看:
1 + 2 + 4 + … + 2 n − 2 = 2 n − 1 − 1 1+2+4+\ldots+2^{n - 2} = 2^{n - 1} - 1 1+2+4+…+2n−2=2n−1−1
3 × ( 2 + 4 + … + 2 n − 2 ) = 3 × ( 2 n − 1 − 2 ) 3\times(2 + 4 + \ldots + 2^{n - 2}) = 3 \times (2^{n - 1} - 2) 3×(2+4+…+2n−2)=3×(2n−1−2)
0 × ( 4 + 8 + … + 2 n − 2 ) = 0 0 \times (4 + 8 + \ldots + 2^{n - 2}) = 0 0×(4+8+…+2n−2)=0
8 + 16 + … + 2 n − 2 = 2 n − 1 − 8 8 + 16 + \ldots + 2^{n - 2} = 2^{n - 1} - 8 8+16+…+2n−2=2n−1−8
… \ldots …
2 n − 2 = 2 n − 1 − 2 n − 2 2^{n - 2} = 2^{n - 1} - 2^{n - 2} 2n−2=2n−1−2n−2
把所有的式子加起来: ( n − 2 ) × 2 n − 1 − ( 1 + 2 + 8 + … + 2 n − 2 ) + 2 × ( 2 n − 1 − 2 ) = ( n − 1 ) × 2 n − 1 + 1 (n - 2) \times 2^{n - 1} - (1 + 2 + 8 + \ldots + 2^{n - 2}) + 2 \times (2^{n - 1} - 2) = (n - 1) \times 2^{n - 1} + 1 (n−2)×2n−1−(1+2+8+…+2n−2)+2×(2n−1−2)=(n−1)×2n−1+1。
正解:
观察到分子是一个带权等比数列,考虑使用错位相减法。
设 S = 1 × 2 0 + 2 × 2 0 + 3 × 2 1 + 4 × 2 2 + … + n × 2 n − 2 S = 1 \times 2^0 + 2 \times 2^0 + 3 \times 2^1 + 4 \times 2^2 + \ldots + n \times 2^{n - 2} S=1×20+2×20+3×21+4×22+…+n×2n−2。
则 2 S = 1 × 2 1 + 2 × 2 1 + 3 × 2 2 + 4 × 2 3 + … + n × 2 n − 1 2S = 1 \times 2^1 + 2 \times 2^1 + 3 \times 2 ^ 2 + 4 \times 2 ^ 3 + \ldots + n \times 2 ^ {n - 1} 2S=1×21+2×21+3×22+4×23+…+n×2n−1。
2 S − S = ( 1 × 2 1 − 1 × 2 0 − 2 × 2 0 ) + ( 2 − 3 ) × 2 1 + ( 3 − 4 ) × 2 2 + … + ( n − 1 − n ) × 2 n − 2 + n × 2 n − 1 2S - S = (1 \times 2^1 - 1 \times 2 ^ 0 - 2 \times 2^0) + (2 - 3) \times 2^1 + (3 - 4) \times 2^2 + \ldots + (n - 1 - n) \times 2^ {n - 2} + n \times 2^{n - 1} 2S−S=(1×21−1×20−2×20)+(2−3)×21+(3−4)×22+…+(n−1−n)×2n−2+n×2n−1
整理一下得到: S = ( n − 1 ) × 2 n − 1 + 1 S = (n - 1) \times 2^{n - 1} + 1 S=(n−1)×2n−1+1。
然后对上面的式子取模,得到分子,套用分数取模得到答案。
注意特判一下 n = 1 n = 1 n=1 的情况,直接输出 1 1 1。
#include<bits/stdc++.h>
using namespace std;
int n;
const int mod = 1000000007;
unsigned long long ans = 0;
unsigned long long ksm(long long x, int y){unsigned long long ans = 1;while(y){if(y & 1){ans *= x;ans %= mod;}x *= x;x %= mod;y >>= 1;}return ans;
}
int main(){freopen("nbc.in", "r", stdin);freopen("nbc.out", "w", stdout);scanf("%d", &n);if(n == 1){printf("1");return 0;}long long t = ksm(2, n - 1);ans = (t * (n - 1) + 1) % mod;printf("%lld", ksm(t, mod - 2) * ans % mod);return 0;
}