2024.8.6
看来还没到底线。今天更惨。昨天说的 \(\text{T3}\) 分最高的规律今天就不灵了。。
这题更是依托答辩,\(\text{T3}\) 两个学校快 \(100\) 人没有一个人有分。
\(\text{T1}\) 考小学奥数捆测,坑死一堆人。
T1 BA
题意:\(n\) 个饼,\(m\) 个烙板,第 \(i\) 个饼有 \(a_i\) 个面。一各单位时间一个板烙一个面,问全烙完的最少时间。
我都想起来 \(5\) 年前好像学的是轮着煎,哎然后自己一手模就忘了啥叫“轮着”了,变成了乱轮发现答案不对,就然后就开始了推暴力,把小样例给过了。每次找到当前序列中最大的 \(m\) 个数去煎,最后煎完次数就是了。这样理论上确实是对的,但这样暴力必然死掉了。
然后就对着我这思路硬搞了 \(1.5\text{h}\) 发现复杂度高的优化不掉,死了。
答案是 \(\lceil\frac{\sum{a_i}}{m}\rceil\),很明显你推一下两个板三个饼,每个饼两个面的经典小学题就能发现这个规律,就是轮着煎,贪心地让烙板不空(我还是觉得好无语,手上和脑子里想的不一样。
然后你就过了大样例,出分的时候捆测就来坑你了,发现只有 \(30\) 分。
为什么?由于 \(a_i\) 没有限定范围,所以有一种特殊情况是,其中一个 \(a_i\) 特比大,导致一直占据着其中一个烙板,别的饼都烙完了它还没烙完。这个时候答案就是 \(\max a_i\) 了,情况条件是 \((m-1)a_i>(\sum a-a_i)\)。特判得到 \(100\) 分。
T2 BB
无语了怎么还是博弈结论题。
题意:\(A,B\) 两人轮流买树点,每个树点有一个权值,每买下一个点所花费的代价是当前点的权值,设这个点的祖先节点中有 \(x_1\) 个点被对手买,它的子节点中有 \(x_2\) 个点被对手买,那么你就要给对手交 \(x_1-x_2\) 的钱。求两个人都最优策略的情况下,\(A\) 为先手最多赚到多少。
考场想的是,既然 \(1\) 号节点占的点最多,那么 \(A\) 肯定优先占根(其实场上也想到了 \(1\) 节点的权值可能会特别大的情况,但是确实想不到其他做法了……)。然后就按着深度逐层往下跑,然后树剖线段树啥都上了,调了半天发现题读错了,调了一会过了小样例,场上我自认为贪心是完全正确的,最终获得了 \(18\) 分的运气分。不过因为这个题没有部分分的原因,这分还算非正解高分……
正解:取点是考虑到价值因素来取的,所以我们先把价值表示出来:
这里 \(val\) 表示每个点的价值,\(S\) 表示子树中有多少个点属于对面,\(F\) 表示祖先中有多少个点属于对面,\(w\) 表示这个点的权值。
求出 \(A\) 的答案(\(\sum\) 后的 \(1\) 省略了,\(fa\) 是根链含自己,\(son\) 是子树含自己):
我们发现
然后发现就可以用 \(siz\) 和 \(dep\) 和 \(A\) 的项来表示出 \(B\) 的项。
式子里有 \(\sum_{v\in{A\cup fa_u}} - \sum_{v\in A \cup son_u}\) ,考虑这个怎么算,其实就是一个树中点的深度和与点的子树大小和作差,那么手模一下其实是 \(0\),即二者相等。
最后 \(Ans = \sum_{u\in A} siz_u-dep_u-w_u\)。把所有的 \(u\) 跑一遍,权值排序,删掉奇数项因为 \(B\) 也很聪明,求和输出。
T3 BC
\(\text{PKUSC2022D1T1}\)
题意:给定两个初始为 \(0\) 的变量 \(x,y\),进行如下随机过程:
- 每一步根据给定的概率从 [\(-m,m\)] 中得到整数 \(d\)。
- 对于 \(x,y\) 中的较小值 \(z\),\(z = \max(0,z+d)\)。
在 \(\max(x,y) \geq n\) 时终止过程,求终止的期望步数,\(n \le 5000,m \le 50\)。
因为有两个 \(\text{rating}\) 在变化,但实际是交替连续的移动直至较小的超过较大的,因此我们可以考虑单一变量的变化。设 \(f_{i,j}\) 表示 \(\text{rating}\) \(i\) 第一次 \(>j\) 时为 \(i+j\) 的概率,\(j \in [1,m]\),按照 \(i\) 从小到大转移。第一步走向 \(k \in [-m,m]\),如果 \(k < 0\) 就利用之前的 \(f_{i+k,*}\) 转移,可以 \(O(m^2)\) 转移,\(k=0\) 时列方程。然后设 \(g_{i,j}\) 表示 \(\max(x,y) = i,\min(x,y) = i-j\) 的答案,利用预处理的 \(f\) 转移;
题目求期望,利用线性性把 \(f,g\) 写成 pair
,重定义加法乘法,复杂度 \(O(nm^2)\)。
const int MOD = 998244353;
inline int qp(int a,int b)
{
int res{1};
while(b){if(b & 1) (res *= a) %= MOD;(a *= a) %= MOD;b >>= 1;}
return res;
}
inline int inv(int x){return qp(x,MOD-2);}
const int inv18 = 205817851;
const int M = 105;
int v[M];
int p[M];
const int N = 1010;
pair<int,int>w[M],f[N][M],g[N+M][M];
inline pair<int,int> operator + (pair<int,int>a,pair<int,int>b)
{return make_pair((a.first += b.first) %= MOD,(a.second += b.second) %= MOD);}
inline pair<int,int> operator * (pair<int,int>a,pair<int,int>b)
{return make_pair(a.first*b.first%MOD,(a.second*b.first + b.second*a.first)%MOD);}
signed main()
{
#ifdef LOCAL
freopen("in.in","r",stdin);
#endif
int n = read(), m = read();
v[m+1] = 0;
for(int i{((m+1)>>1)+1};i<=m;i++) v[i] = v[i-1]+1;
for(int i{((m+1)>>1)-1};i>=1;i--) v[i] = v[i+1]-1;
for(int i{};i<=m<<1;i++) p[i] = inv18 * read() % MOD;
// for(int i{};i<=m<<1;i++) writeln(p[i]);
for(int i{};i<=n-1;i++)
{
for(int j{};j<=m<<1;j++) w[j] = make_pair(0,0);
for(int j{};j<=m<<1;j++)
(w[max(-i,j-m) + m].first += p[j]) %= MOD;
for(int j{};j<=m<<1;j++) w[j].second = w[j].first;
for(int j{max(0LL,m-i)};j<=m-1;j++)
for(int k{1};k<=m;k++) w[j+k] = w[j+k] + w[j] * f[i+j-m][k];
int nowinv = inv(1-w[m].first+MOD);
for(int j{1};j<=m;j++)
{
f[i][j].first = w[j+m].first * nowinv % MOD;
f[i][j].second = w[j+m].second + (w[m].second * f[i][j].first) % MOD;
(f[i][j].second *= nowinv) %= MOD;
}
}
g[0][0] = make_pair(1,0);
for(int i{};i<=n-1;i++)
for(int j{min(i,m)};j>=0;j--)
{
for(int k{1};k<=j;k++) g[i][j-k] = g[i][j-k]+ g[i][j] * f[i-j][k];
for(int k{j+1};k<=m;k++)
g[i-j+k][k-j] = g[i-j+k][k-j]+g[i][j] * f[i-j][k];
// writeln(g[i-j+k][k-j]);
}
int ans{};
for(int i{n};i<=n+m;i++)
for(int j{};j<=m;j++) (ans += g[i][j].second) %= MOD;
writeln(ans);
return 0;
}
T4 BD
题意:有 \(n\) 个数 \(w_i\) 成一排,选出至少一个不交的区间,并且每个区间里数的最大公约数相同,问有多少种方案使 \(i\) 在一个区间里。
看不懂。
50pts
预处理每种最小区间 \(l,r\) 和当前 \(\gcd\),组合区间得方案。先设某个区间包含 \(i\),维护这个区间前后的方案数。每个段的方案就是从所有满足 \(l\) 大于当前 \(r\) 的段转移来,方案数为这些段的方案数和 \(+1\)(加上单独成段)。
如何计算总方案数?先不考虑单独这个段(注意这个段是钦定要选的),考虑所有两侧的组合,根据 左右、仅左、仅右,容易想到 (左方案 \(+1\)) \(\times\) (右方案 \(+1\))\(-1\)。然后还要再加上这个段单独,所以不用减那个 \(1\)。