题目描述
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;
}