: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); }

【OI 档案-2025】CSP 赛前集训记(初赛后+复赛)

复赛前 - 第一周(9.22 ~ 9.28)

Day1 - 周一

斌斌感冒了 awa,这天只能晚自习坐大牢了。

Day2 - 周二

直接来模拟赛吗 0.0,直接从 lzm 搬运吗?有点意思,但是被薄纱,155pts,rk5,没救了。

小梦学习计网

枚举+模拟,lzm 标黄题,实际顶多评红,但是被薄纱,某人对自己的位运算太自信了。但是确实很简单,没啥好讲的。

小梦的跳跃游戏

依旧被薄纱,难绷,破环成链 + 分层图最短路,但是不会,连破环成链都忘了,知道是最短路,但是不会建图,两个月没复习图论不行了。
破环成链后,由于每多往后面访问一个节点,权重多一,就可以分层建图,给每个节点连条边权为一的边,再给原点的连回一条无权边,就可以得到答案。

T3 和 T4 没写,T3 骗了分,但是因为不可以总司令输出 YES,唉。

自主留下来补题,补出来了会把记录补上,但是懒得贴代码了,这会导致篇幅过长。

Day3 - 周三

这周都是模拟赛。

P1931 套利

就是 SPFA 找正环嘛0.0,怎么评的绿?

UVA1400 "Ray, Pass me the dishes!"

区间合并,静态求区间最大子段和最左子区间,就……区间合并线段树呗……没啥好讲的,但是半小时出正解,调错一小时……

Day4 - 周四

斌斌说这把模拟赛貌似是最接近今年 \(S\) 的一把。

归去来兮女士的旅行(red)

T1 感觉可以评黄。
对凭证排序,然后枚举每个凭证要求低于 \(i\) 的子图,跑 floyd 求最短路即可。

下北泽大天使的树上染色(yellow)

T2 就上位绿/蓝吗 qwq
先对颜色离散化,然后离线处理,把每个操作(查询和修改)都打到对应的节点上,遍历树,枚举到的节点处理修改和查询。
修改操作用若干个单调栈和 BIT 维护,每个颜色对应的单调栈记录每个颜色被染上时间戳(操作),维护单调递减。如果栈为空或栈内存储的时间戳比当前的大,当前操作的时间戳为 \(l\) 设栈顶为 \(r\)(若栈为空则以操作数即操作时间戳末尾为 \(r\)),则时间戳区间 [l , r - 1] 内的所有查询的颜色总数加一,BIT 维护区间修单点查即可。注意查询时候需特判查询传参的颜色是否被染上,如果未被染上,则答案加一,判断方法与更新单调栈一致。回溯时需回溯,令单调栈与 BIT 做反操作即可。
\(A\) 是窝滴,但是不明白为啥没几个入敲暴力……

后面的题没看 awa,一蓝一紫……

下大雨了,和斌斌肩并肩(蹭伞)。

中间莫名其妙段了。

10-28

Day 几不知道了。由于被强制做记录故重新启动。

DNA 序列(DNA)

哈希题啊,但是忘了怎么写哈希了 qwq,所以……

思路大概就是维护一个长度为 \(k\) 的四进制数,类似于一个滑动窗口,就是除以 \(4\) 后加上右边新加的数乘上 \(4^k\),就可以得到其对应的哈希值,取模嘛……就需要逆元了,所以就自然溢出了(不是,自然溢出带除法也不太对吧……),然后统计出现次数最多的就过了。

小奇采药(medicine)

0-1 背包板子?但是背包容量 \(\le 10^9\)所以这道题是玄学

咳咳,对于这道题目,我们只能搜索,由于数据随机,所以……启发式搜索神力!

直接 A* 就干完了。

估价函数长这样:

inline long long f(long long t, long long v) {
    long long h = 0;
    for (int i = t + 1 ; i <= n ; i++) {
        if (v >= a[i].c){
            v -= a[i].c;
            h += a[i].v;
        }
        else return (long long)(h + v * a[i].cost);
    }
    return h;
}

脑洞治疗仪 (brainhole)

区间合并线段树裸题啊……

本题要求维护最长连续 \(0\),但和最大子段和类似。

维护最大子段和:

1、最大子段和合并:

有三种情况,如图:

对这三种情况取最大值就是合并后的最大子段和,查询时的合并是将最大后缀和合并,分类讨论判断是否需要同 LCA 一同合并,如果需要,可将两个最大后缀和与 \(0\) 取最大值,因为 LCA 可以选择不之合并。

2、区间和合并:
直接将两个区间和相加即可。

3、最大前缀和合并:
有两种情况,第一种最大前缀和就是 \(c_u\),第二种是 \(b_u+c_v\),然后对两种情况取最大值。

4、最大后缀和合并:
同最大前缀和合并一样,有两种情况,第一种是 \(d_v\),第二种是 \(b_v+d_u\),对两种情况取最大值即可。

综上可以得出:
\(a_f=\max(c_v+d_u,a_u,a_v),b_f=b_u+b_v,c_f=\max(c_u,b_u+c_v),d_f=\max(d_v,b_v+d_u)\)

然后我们在分别维护区间 \(0\) 的数量,就可以得到区间长度。

在合并是特判区间长度是否等于前后缀最大值,就可以得到最大连续长度。

然后维护区间赋值、区间求和、区间最长连续 \(0\) 即可

至于填补,线段树上二分找到操作边界进行赋值即可。

然后就干完了。

洗衣服(clothes)

贪心签到题,我们先处理洗衣机,用小根堆维护最小完成时间,求得每件衣服洗完的时间。然后处理烘干机,同样用一个小根堆维护最小完成时间,求得每件衣服烘干的时间。然后显然的一点,洗完的时间越晚,其期望烘干的时间就应该越快,所以小配大即可。

逗号播撒机(comma)

把字符串离散成整型,然后用带权并查集维护两个字符串在数据中是否存在相邻逗号,最后特殊处理打印即可。

地下城市(city)

Tarjan 跑一遍点双求出有点双连通分量,然后遍历每一个分量,统计分量中割点数量,若割点数量为一,那么选择方案数为分量大小减一(排除割点);反正如果大于一,那么就不需要建出口了,贡献为零。如果没有割点,即该图为点双连通图,方案数就为 \(C_2^n\),然后就干完了。

锦标赛 (tournament)


按能力值升序排序,求得每种元素的差值,从后往前遍历,对于差值小于 \(K\) 的玩家都是可能胜利的玩家。

幸运数 (lucky)


用队列加链表维护,先遍历序列把第一轮选中的 \(i\) 入队,然后遍历一遍队列算一遍贡献,算完后再遍历一遍在链表上进行删除,并查看删除后是否可以组成新的 47,把它们入队。重复以上操作直到队列为空为止。

序列 (seq)


可以求出 \(a_i\) 变为 \(b_i\) 的操作数 \(c_i\),组成序列 \(c\),将其转化为差分数组,目标是将其清零,直接贪心消除正负对应的差分数组即可。

01 串 (binary)


不难发现 \(2^i \bmod 3\) 中,若 \(i\bmod 2 = 0\)\(2^i \bmod 3=1\);反之,\(2^i \bmod 3=2\),所以就可以分讨,写出如下逆天的代码,分讨的思路看代码应该很容易看出来。

Code
if(n == 1 || ((n & 1) && (m <= 1))) {
	printf("-1 \n-1 \n");
	continue;
} else if(m == 0) {
	for(int i = 1 ; i <= n ; i ++) printf("1");
	printf("\n");
	for(int i = 1 ; i <= n ; i ++) printf("1");
	printf("\n");
	continue;
}
int now = p[n + m - 1];
n --;
if(now == 1) {
	if(n & 1) {
		printf("1");
		for(int i = 1 ; i < n ; i ++) printf("1");
		printf("10");
		for(int i = 1 ; i < m ; i ++) printf("0");
		printf("\n");	
		printf("1");
		if(m & 1) {
			for(int i = 1 ; i < m ; i ++) printf("0");
			printf("10");
			for(int i = 1 ; i < n ; i ++) printf("1");
			printf("\n");					
		} else {
			for(int i = 1 ; i < m ; i ++) printf("0");
			printf("01");
			for(int i = 1 ; i < n ; i ++) printf("1");
			printf("\n");					
		}
	} else {
		printf("1");
		for(int i = 2 ; i < n ; i ++) printf("1");
		printf("0101");
		for(int i = 2 ; i < m ; i ++) printf("0");
		printf("\n");		
		printf("1");
		if(m & 1) {
			for(int i = 2 ; i < m ; i ++) printf("0");
			printf("1010");
			for(int i = 2 ; i < n ; i ++) printf("1");
			printf("\n");					
		} else {
			for(int i = 2 ; i < m ; i ++) printf("0");
			printf("0101");
			for(int i = 2 ; i < n ; i ++) printf("1");
			printf("\n");					
		}
	}
} else {
	if(n & 1) {
		printf("1");
		for(int i = 1 ; i < n ; i ++) printf("1");
		printf("10");
		for(int i = 1 ; i < m ; i ++) printf("0");
		printf("\n");					
		printf("1");
		if(m & 1) {
			for(int i = 1 ; i < m ; i ++) printf("0");
			printf("10");
			for(int i = 1 ; i < n ; i ++) printf("1");
			printf("\n");					
		} else {
			for(int i = 1 ; i < m ; i ++) printf("0");
			printf("01");
			for(int i = 1 ; i < n ; i ++) printf("1");
			printf("\n");					
		}
	} else {
		printf("1");
		for(int i = 2 ; i < n ; i ++) printf("1");
		printf("0101");
		for(int i = 2 ; i < m ; i ++) printf("0");
		printf("\n");					
		printf("1");
		if(m & 1) {
			for(int i = 2 ; i < m ; i ++) printf("0");
			printf("1010");
			for(int i = 2 ; i < n ; i ++) printf("1");
			printf("\n");					
		} else {
			for(int i = 2 ; i < m ; i ++) printf("0");
			printf("0101");
			for(int i = 2 ; i < n ; i ++) printf("1");
			printf("\n");					
		}
	}
}
posted @ 2025-09-23 22:00  雨落潇湘夜  阅读(23)  评论(0)    收藏  举报
我的页脚图片