比赛过程
数学场做起来有点别扭,但是出题还挺爽的,代码也不长,主要是太难想了,一些定理还不知道。
题解
1001
题意
有一个直角四面体,组成三个直角的三条边长度分别为 a , b , c a,b,c a,b,c,而 a , b , c a,b,c a,b,c 是属于 [ 1 , n ] [1,n] [1,n] 中等概率的随机的数,设这个直角顶点到斜边的距离是 h h h ,求 1 h 2 \frac{1}{h^2} h21 的期望。
解法
刚开始看过的人多以为是先求出变得期望,再求答案的期望,但是样例都过不了。这道题必须要用到三维勾股定理和体积公式: S 1 2 + S 2 2 + S 3 2 = S 2 S_1^2+S_2^2+S_3^2=S^2 S12+S22+S32=S2 V = S 1 ∗ a 3 V=\frac{S_1*a}{3} V=3S1∗a V = S 2 ∗ b 3 V=\frac{S_2*b}{3} V=3S2∗b V = S 3 ∗ c 3 V=\frac{S_3*c}{3} V=3S3∗c 解得: 1 a 2 + 1 b 2 + 1 c 2 = 1 h 2 \frac{1}{a^2}+\frac{1}{b^2}+\frac{1}{c^2}=\frac{1}{h^2} a21+b21+c21=h21 再根据期望公式: ∵ E ( x ) = ∑ i = 1 n p i ∗ x i \because E(x)=\sum_{i=1}^{n}p_i*x_i ∵E(x)=i=1∑npi∗xi ∴ E ( 1 a 2 + 1 b 2 + 1 c 2 ) = 3 ∗ E ( 1 a 2 ) = 3 n ∗ ∑ i = 1 n 1 i 2 \therefore E(\frac{1}{a^2}+\frac{1}{b^2}+\frac{1}{c^2})=3*E(\frac{1}{a^2})=\frac{3}{n}*\sum_{i=1}^{n}\frac{1}{i^2} ∴E(a21+b21+c21)=3∗E(a21)=n3∗i=1∑ni21 综上所述只要预处理出 ∑ i = 1 n 1 i 2 \sum_{i=1}^{n}\frac{1}{i^2} ∑i=1ni21 即可。预处理循环的 i i i 如果是 int 类型的会 TLE (雾)
代码
const int maxn = 6e6 + 5;
ll f[maxn];
void init(){
for (ll i=1;i<maxn;++i){
f[i] = (powmod(i * i, mod - 2) + f[i - 1]) % mod;
}
}
int main() {
IO;
init();
int t;
cin>>t;
while(t--){
ll n;
cin >> n;
ll ni = 3 * powmod(n, mod - 2);
cout << mul(ni, f[n]) << endl;
}
return 0;
}
1003
题意
一张纸有上下两个面,将 n n n 张纸向右折 k k k 次,然后从上到下写上 2 ∗ n ∗ 2 k 2*n*2^k 2∗n∗2k 个数字序列 p i p_i pi,让后将纸展开,从上到下,从左到右输出刚才的数字。
解法
想象
n
n
n 张纸展开的过程,每次截取上半部分,倒置(左转 90 度)后将其放置于剩余部分的左侧,模拟
k
k
k 次即可。注意 deque 会MLE,vector 不会。
代码
const int maxn = 5e5 + 5;
vector<int> q[maxn];
int n, k, cnt;
int main() {
IO;
int T;
cin >> T;
while(T--){
cin >> n >> k;
cnt = n << (k + 1);
FOR(i,1,cnt) q[i].clear();
FOR(i,1,cnt){
int x;
cin >> x;
q[i].push_back(x);
}
int x = 1;
FOR(i,1,k){
int mid = (cnt + x) >> 1;
FOR(i,x,mid){
int siz = q[i].size();
for(int j = siz - 1;j>=0;j--)
q[mid+mid-i+1].push_back(q[i][j]);
}
x = mid + 1;
}
FOR(i,x,cnt){
for(int j = q[i].size()-1;j>=0;j--){
if(j==0&&i==cnt){
cout<<q[i][j]<<endl;
}
else{
cout<<q[i][j]<<' ';
}
}
}
}
return 0;
}
1009
题意
把一张纸随机对折 n n n 次,然后从中间横着切一刀竖着切一刀,问展开后得到分开的纸张的期望。
解法
依旧是数学推导题,注意到往上折和往下折效果一样,往左折和往右折效果也一样,因此只需要统计一下上下方向折的次数,左右方向折的次数,分别记为 a , b a,b a,b,稍加思索得到公式: a n s = ( 2 a + 1 ) ∗ ( 2 b + 1 ) ans=(2^{a}+1)*(2^{b}+1) ans=(2a+1)∗(2b+1) a + b = n a+b=n a+b=n 于是: E ( a n s ) = E ( ( 2 x + 1 ) ∗ ( 2 n − x + 1 ) ) E(ans)=E((2^{x}+1)*(2^{n-x}+1)) E(ans)=E((2x+1)∗(2n−x+1)) E ( a n s ) = E ( 2 x + 2 n − x ) + 2 n + 1 E(ans)=E(2^{x}+2^{n-x})+2^{n}+1 E(ans)=E(2x+2n−x)+2n+1 E ( a n s ) = 1 2 n ∑ x = 1 n C n x ( 2 x + 2 n − x ) + 2 n + 1 E(ans)=\frac{1}{2^{n}}\sum_{x=1}^{n}C_{n}^{x}(2^x+2^{n-x})+2^{n}+1 E(ans)=2n1x=1∑nCnx(2x+2n−x)+2n+1 ∑ x = 1 n C n x ∗ 2 x = ∑ x = 1 n C n x ∗ 2 x ∗ 1 n − x = ( 2 + 1 ) n = 3 n \sum_{x=1}^{n}C_{n}^{x}*2^x=\sum_{x=1}^{n}C_{n}^{x}*2^x*1^{n-x}=(2+1)^n=3^n x=1∑nCnx∗2x=x=1∑nCnx∗2x∗1n−x=(2+1)n=3n ∑ x = 1 n C n x ∗ 2 n − x = ∑ x = 1 n C n x ∗ 2 n − x ∗ 1 x = ( 2 + 1 ) n = 3 n \sum_{x=1}^{n}C_{n}^{x}*2^{n-x}=\sum_{x=1}^{n}C_{n}^{x}*2^{n-x}*1^{x}=(2+1)^n=3^n x=1∑nCnx∗2n−x=x=1∑nCnx∗2n−x∗1x=(2+1)n=3n 综上所述: E ( a n s ) = 2 ∗ 3 n 2 n + 2 n + 1 E(ans)=\frac{2*3^n}{2^n}+2^{n}+1 E(ans)=2n2∗3n+2n+1
代码
int main() {
IO;
int t;
cin>>t;
while(t--){
ll n;
cin >> n;
if(n==0)
cout << 4 << endl;
else{
ll ni = powmod(powmod(2, n - 1), mod - 2);
ll ans = (mul(powmod(3, n), ni) + powmod(2, n) + 1) % mod;
cout << ans << endl;
}
}
return 0;
}