总结
额。。。这次比赛嘛,做的一般般滴。
T1:一道水题,之前讲过的,就是判断xy的祖宗关系,但是考试时完全忘了,傻逼的用并查集做了一个多小时。。。。结果愉快的爆0。
正解:遍历树,求出每个点的st[x],ed[x],st[x]表示第一次访问这个点的时间,ed[x]表示最后一次访问这个点的时间,说得简单点其实就是以x为根的子树里最后一个点的st。
当时就是搞不懂ed搞了大半天,原来是这么简单。。。(我吐血)
T2:这是一道纯粹的数学题,因为我数学最强,所以果断AC了。(每次碰到这种数学题我都果断AC)
正解:先弄个全排列,设n=3
那么a队的队员出场顺序顺序为:
123
132
213
231
312
321
(b队出场顺序永远是123,不用全排列,否则会重复)
我们观察后发现:a队的每个队员都和对方的每一个队员分别比赛(n-1)!场,b队也是如此。这样就好办了。
因为只有碰到比自己弱的人才能得分,所以先把ab两个序列按小到大排个序。
排完序后:
首先for一遍枚举a队每个人对答案的贡献。
当枚举到一个人时,求出一个j(b[j]<=a[i]且j最大),然后算得分。
怎么样才能快速算得分呢?一个个枚举的话会痛快的超时,所以我们要优化一下。
先看公式,得分为(a-b)^2,把这个东西拆分后变成:a^2-2ab+b^2。
然后看第一项a^2,因为第一项出现j次,所以直接乘j。
再看第二项,因为b是从b[1]到b[j]的,所以在前面先求出前缀和,然后用乘法分配率将其合并,变成2a*前缀和[j]即可。
最后看第三项,展开后变成b[1]^2+b[2]^2+b[3]^2+...+b[j]^2,所以和前面一样,求出另一个前缀和,就是每一项的平方相加的和。最后再加上 前缀和2[j]即可。
b队得分也是如此。
这里还有一个问题,就是每两人之间比赛(n-1)!场,如果直接乘肯定boom,所以要找下规律。我们发现全排列的话一共有n!种方案数,也就是说答案最后要除以总方案数,这样就好办了,把(n-1)!和n!抵消掉,在计算过程中不用乘(n-1)!,只需要在最后除以n就行了。
T3:也是一道比较水的题,推了一会就想出是一道dp,求分别满足两种情况的部分考试时已经打出来了,就是不知道如何去重啊啊啊啊啊啊,最后无奈地交了暴力,水20分。。唉唉唉
正解:设f[i,j]表示到了一共有i位,和为j的方案数。f[i,j]=∑(f[i-1,j-c[k]) (1<=i<=n,0<=j<=max*i,1<=k<=l)(备注:max为s中最大的数字,l为s的长度)
求出来之后,符合第一种情况的方案数为∑(f[n,i]*f[n,i]),符合第二种情况的方案数同上,乘上2就好了,变量最好定成int64,这样不会boom。
再看看如何去重。(当时讲题时完全听不懂,后来问人才做出的)
sum表示重复的方案数,sum=∑(f[(n+1)div 2,i]*f[n div 2,j])^2
(0<=i<=(n+1)div 2*max,0<=j<=n div 2*max)
但是如果两重循环的话你会十分痛快的超时
优化:用两个变量分别求出奇数和偶数的方案数,最后乘起来即可。