:root { --bg-color: #ffffff; --text-color: #333333; --header-bg: #f5f5f5; } .night-mode { --bg-color: #1a1a1a; --text-color: #e0e0e0; --header-bg: #2d2d2d; } body { background: var(--bg-color); color: var(--text-color); } .header { background: var(--header-bg); }

信奥大联赛周赛(提高组)#2515-S 赛后盘点

战果

黄绿蓝紫,248 pts,rk 4,T3 双指针维护反了qwq,原因两个:样例太水,只给 3h。赛后略改过 T3,气死了,样例为啥这么水?

D1505 E-小梦的学术论文

简单二分答案0.0,非常板,没啥好讲的。秒了。

核心代码
int check(int k) {
	int h = 0;
	for(int i = 1 ; i <= n ; i ++) {
		if(a[i] >= k) h += b[i];
	}
	return h >= k;
}

D1506 F-小梦的糖果游戏

维护一个前缀 \(dp_{i,j}\) 和一个后缀 \(dp2_{i,j}\) 数组,两者都表示 \([1,i]\)\([i,n]\) 中的数组成 \(j\) 的方案数。算出来后根据乘法原理相乘合并答案即可。

核心代码
memset(dp1 , 0 , sizeof(dp1));
memset(dp2 , 0 , sizeof(dp2));
in(n);
dp1[0][0] = dp2[n + 1][0] = 1;
int m = 0;
for(int i = 1 ; i <= n ; i ++) in(a[i]) , m += a[i];
for(int i = 1 ; i <= n ; i ++) {
	for(int j = 0 ; j <= m ; j ++) {
		dp1[i][j] = dp1[i - 1][j];
		if (j >= a[i])dp1[i][j] += dp1[i - 1][j - a[i]];
		dp1[i][j] %= mod;
	}
}
for(int i = n ; i ; i --) {
	for(int j = 0 ; j <= m ; j ++) {
		dp2[i][j] = dp2[i + 1][j];
		if (j >= a[i]) dp2[i][j] += dp2[i + 1][j - a[i]];
		dp2[i][j] %= mod;
	}
}
int ans = 0;
for(int i = 0 ; i <= n ; i ++) {
	for(int j = 0 ; j <= m ; j ++) {
		ans += dp1[i][j] * dp2[i + 1][j] , ans %= mod;
	}
}

D1507 G-小梦的物理小球

不知道是第几次赛时差点切蓝了 www
一眼期望 dp。求直接落到每个线段后的期望和,定义函数 \(f(x)\) 表示从横坐标 \(x\) 向下坠落落到的第一条线段或坐标轴。
得转换方程:

\[dp_i=\frac{dp_{f(l)}+dp_{f(r)}}{2} \]

求得 \(2\) 关于 \(998244353\) 的逆元为 \(499122177\),这样可以处理分数取模。
难点在于 \(f(x)\),暴力思路是对线段按纵坐标排序,然后线性枚举,这么做的复杂度是 \(O(n^2+qn)\) 的,可以拿到 \(40\) 分。
考虑按纵坐标从小到大添加线段,标记区间 \([l,r]\) 的最高层线段,可以用线段树维护区间赋值,单点查询,注意需要离散化。
这样复杂度就降到了 \(O((n+q)\log n)\)
在处理查询时需要求得其下落的第一个线段,因此需要重复一遍增加线段的步骤,从下往上枚举,根据查询的高度增加对应的线段,这里可以用双指针来维护。
具体实现并不困难,思路也不是很难想,夹杂了两到三个内容,评蓝没问题。

posted @ 2025-10-02 00:33  雨落潇湘夜  阅读(11)  评论(0)    收藏  举报
我的页脚图片