前言
我的codeforces账号:keguaiguai
求关注、求关注、求关注
基本情况
济南站情况大致是:
1题快:铜牌
2题快:银牌
4题整:金牌
8题快:出线
我们队伍第一次参加区域赛,由于做题时紧张,又赶上期中考试和数学竞赛,于是爆零了。
难度分布
C、D、J、K四题是竞赛中过题队伍数在100支以上的,但是在本次竞赛中一共做出4题的只有35支队伍。
K-签到题
C-铜牌题
J-银牌题
D-银牌题
其余9题为金牌题。因难度过高,网上题解也很少,故只能提供铜银题的题解。
K 寻找椎名真冬
命题人
jiangly
题目背景
Mafuyu:全名Shiina Mafuyu,即椎名真冬,日本动画《学生会的一己之见》的女主角之一。

Kanade:全名Tachibana Kanade,即立华奏,日本动画《Angle Beats!》及衍生作品中人物。

Sekai:“Sekai”是一个“源于想象力“的世界,取材于近代日本的涩谷,初音未来等歌手将出现在这里,是《世界计划 彩色舞台》中的世界。游戏英文名称Project Sekai,是SEGA GAMES与Colorful Palette合作开发的一款初音企划手游。

题目翻译
椎名真冬藏在了世界里,立华奏正在寻找她。
这个世界,只有许多房间。世界里有n间房,编号1到n。另外,n-1对房间直接由通道连接,这样就可以通过使用一个或多个通道,从一间房移动到其它任意一间。也就是说,世界里的房间形成了一棵树。
立华奏在1号房间,她知道椎名真冬也许等可能地藏在除了1号房间的其它任意一个房间。每一秒钟,立华奏能移动到与她目前所在房间相邻的房间。只要立华奏和椎名真冬处于同一间房,立华奏马上就能找到椎名真冬。如果立华奏采取最佳策略,那么立华奏找到椎名真冬的最短期望时间是多少?
思路
本题求的是期望用时。这是一个非透明信息静态博弈,通过分析样例可以发现,无论立华奏采取何种策略从1号根节点开始遍历这棵树,求得的最短期望时间都相同。因此先用vector建立无向图存储树形结构,然后以一号结点为根结点开始用dfs递归遍历整棵树。注意在进栈和出栈时,根据深度递归的特性,令当前时间加1,模拟走过某个结点和离开某个结点时,时间流动的过程。每先进入一个结点,就令总时间加上当前的时间。最后让时间总和除以n-1,就得到n-1个结点的平均期望时间。
代码
#include<bits/stdc++.h>
using namespace std;
const int maxn = 105;
vector<int> son[maxn];
int ans, tim;
void dfs(int cur, int fa) {
tim++;
for (int i = 0; i < son[cur].size(); i++) {
if (son[cur][i] != fa) {
ans += tim;
dfs(son[cur][i], cur);
}
}
tim++;
}
int main()
{
int t;
cin >> t;
while (t--) {
int n;
cin >> n;
int a, b;
for (int i = 1; i <= n; i++)son[i].clear();
for (int i = 1; i < n; i++) {
cin >> a >> b;
son[a].push_back(b);
son[b].push_back(a);
}
ans = 0, tim = 0;
dfs(1, 0);
double x = ans*1.0 / (n - 1);
printf("%.10lf\n", x);
}
return 0;
}
感想
第一次参加区域赛爆零了,当时做这题不知道为什么,考场上调了几个小时都没调出来,寒假有时间了现在自己再做一遍,发现这题非常简单,想了一会,直接写代码就AC了。不知道考试时中了什么魔咒,能紧张成那个样子。记得当时应该是思路想偏了,一开始就是按照这种思路写的代码,只是交了没过,就没有再去修改代码,而是换了其他思路写这个题,三个人越写心态越崩,就炸掉了。我记得当时dfs写得非常复杂,绝对是没有利用栈的特性,而是在那里瞎写。
这次比赛,获得铜牌的条件是这道题在半小时之内做出来。只需要快速做出这一道题,就可以拿铜牌。现在我后悔也来不及了,安心准备昆明站吧。
J 行列式
题目背景
Alice:爱丽丝·玛格特洛伊德,系列作品《东方project》中的角色。

题目翻译
爱丽丝想利用矩阵 A T A A^{T}A ATA的优良性质求矩阵 A T A A^{T}A ATA的行列式。将A的行列式记为det(A),满足det( A T A A^{T}A ATA)= d e t ( A ) 2 det(A)^{2} det(A)2。爱丽丝利用这个性质求绝对值|det(A)|。但不幸的是,当|det(A)|≠0,这个方法无法得出det(A)是正的还是负的。
已知矩阵A和det(A)的绝对值,判断A是正的还是负的。
数据大小:|det(A)|的绝对值不超过10000位,矩阵中每个元素不超过 1 0 9 10^{9} 109。
思路
由于|det(A)|的绝对值过于巨大,不可能直接通过高斯消元求出det(A)。只能考虑用某种手段降低数据大小,由此可以想到取模。|det(A)|的绝对值已知,但它是个大数,可以利用大数取模模板对det(A)的绝对值取模,再利用高斯消元在取模意义下求det(A)取模后的值。正数和负数取模后得到的值不同,但需满足一定条件。推导如下:
推导
设有正整数x, x m o d p = = q xmodp==q xmodp==q,则q<p, x = k p + q x=kp+q x=kp+q。故 − x m o d p = = ( − k p − q ) m o d p = = ( − k p − q + k p + p ) m o d p = = ( p − q ) m o d p = = p − q -x mod p ==(-kp-q) mod p==(-kp-q+kp+p)modp==(p-q)modp==p-q −xmodp==(−kp−q)modp==(−kp−q+kp+p)modp==(p−q)modp==p−q。若 x m o d p ≠ − x m o d p xmodp≠-xmodp xmodp=−xmodp,需满足q≠p-q,即p≠2q。因此当p为奇数时,p不为2的倍数,满足正数和负数取模后得到的值不同。
大数取模
如何对大数取模?以1234为例,将大整数分解成这种形式: 1234 = ( ( 1 ∗ 10 + 2 ) ∗ 10 + 3 ) ∗ 10 + 4 1234=((1*10+2)*10+3)*10+4 1234=((1∗10+2)∗10+3)∗10+4,即从高位到低位,分别对大数的每一位上的数取模再乘10,再加上下一位上的数重复上述操作。
模意义下高斯消元
如何在高斯消元时取模?首先回顾高斯消元的原理。对于一个矩阵,可以先以第一行为参考,第二至n行分别减去第一行乘一个倍数,使得第二至n行的第一个元素恰好为0。再以第二行为参考,重复上述过程,直到化为行阶梯型矩阵。如果是解多元线性方程组,此时由这个矩阵的最后一行,直接得出最后一个未知量的值。然后代入,得到倒数第二行的倒数第二个未知量的值,以此类推,直到求出所有未知量的值。如果是求这个矩阵的行列式的值,直接将对角线上的所有元素相乘即可。对于取模,在算倍数时需要用除法,则利用费马小定理求模意义下的除法值。回顾一下费马小定理:
( a ÷ b ) m o d (a÷b) mod (a÷b)mod p = = ( a ∗ i n v ( b ) ) m o d p p == (a * inv(b)) mod p p==(a∗inv(b))modp
其中(inv(b) == b p − 2 b^{p-2} bp−2)mod p,且b与p互素
b p − 2 b^{p-2} bp−2<

本文作者回顾了在编程区域赛中的经历,详细分析了四道题目——寻找椎名真冬、行列式判断、等差数列构造和最佳策略问题的解题思路和难点。作者指出,题目涉及动态规划、博弈论、大数取模和矩阵运算等多个知识点,同时也分享了比赛中遇到的心态调整和策略选择的重要性。
3205

被折叠的 条评论
为什么被折叠?



