2025 QBXT集训
该篇文章于2025/10/6时创建,正常作用是用来记录集训期间的一些内容
但是由于作者在这场集训表现太过唐氏,于是打算用来记录考场上范的一些弱智错误以及唐氏题目
day1
T1由于忘了考虑两个数相等的情况导致100->60 ,在赛后将一行代码挪一个位置获得满分
T2数位DP,T3神秘DP
其余题目正常发挥,60+30+0+10=100
day2
T1(区间)
波特有 \(n\) 个区间 \([l_1, r_1], [l_2, r_2], . . . , [l_n , r_n ]\)。他想划分这些区间,我们称一个划分是好的,当且仅当:
- 所有区间被划分成恰好两个非空子集。
- 对于两个有公共点的区间,它们在同一个子集中。
波特打算删掉若干个区间(可能一个也不删),使的存在一个好的划分。波特想知道最少要删掉多少个区间。
无解输出 \(-1\) ,\(0 \leq n \leq 2\times 10^5 , 1 \leq l_i \leq r_i \leq 10^9\)
- 发现我们并不关注某一个区间的长度而是只关注区间端点之间的大小,因此先将所有区间端点离散化
- 称划分后的两个集合之间的间隔为分界线(例如称 \(\{[1,3],[2,4]\} \ \{[7,8]\}\) 之间的分界线为 \(5\) 或 \(6\) ),那么我们只需要枚举分界线,沿着分界线分开两个区间,记录答案并取最小值即可。
- 具体的,枚举分界线,将通过分界线的区间全部删除后,检查左右两侧是否有区间以判断分界线是否合法,若合法则将删除区间数计入贡献,最后对所有删除区间数求出最小值。
- 发现合法的分界线一定在 \(( \displaystyle \min^n_{i=1} r_i,\displaystyle \max^n_{i=1}l_i)\) 之中(因为在这个区间内分界线左右两边至少会有一个区间),直接枚举即可。
(这里有个细节,为防止类似 \([1,2]\ [3,4]\) 这种相邻区间之间分界线无法判定情况,我们把每个区间端点都乘 \(2\),这样上面区间就会被整成\([2,4]\ [6,8]\) 就可以通过枚举 \(5\) 来作为分界线了)
(代码不放,在U盘里)
T2(染色)
波特有一个 \(n\times m\) 的矩阵,他要将其填入 \(0\) 和 \(1\) 两种颜色。
我们称一个矩阵是好的,当且仅当满足以下条件:
- 每个点都有颜色。
- 对于每个 \(2\times2\) 的子矩阵,颜色 \(0\) 的格子个数为偶数。
矩阵初始为全为无色。波特现在要进行 \(q\) 次如下操作:
x y c:表示将矩阵第 \(x\) 行 \(y\) 列的格子涂上颜色 \(c\),保证当前格子之前没有涂色。在每次操作结束后以及第一次操作前。你需要帮波特计算出,如果对未被染色的格子染色,有多少染色方案是好的,答案对 \(10^9+7\) 取模。
- 先考虑一种情况,当一个 \(2 \times 2\) 的子矩阵只有右下角没有颜色,其余地方都有颜色,那么右下角应该填什么颜色来是这个矩阵是好的?
- 令 \(f_{i,j}\) 为第 \(i\) 行第 \(j\) 列的颜色,则
- 推广得到
- 由此发现矩阵的第一行和第一列都确定下来后,那么矩阵的其他元素也就确定了。我们得到一个结论,矩阵由其第一行和第一列决定。
- 通过这个结论, \(q=0\) 的情况就已经搞定:答案为\(2^{n+m-1}\),因为只会有 \(n+m-1\)个位置可以随意改变,其他位置都有这些位置决定。
- 接下来考虑有操作情况,发现规定矩阵的 \(f_{i,j}\) 相当于给 \(f_{i,1}\) 和 \(f_{1,j}\) 加一个两者必须相同或不相同的限制。题意转化为了
给定 m+n-1 个变量,若干个关于变量值限制,求总共有多少种赋值方案。可用扩展域并查集解决,答案为 \(2^{连通块个数-1}\)
day3
正常发挥的一次
T1签到,T2 DP,T3神秘二项式反演,T4不会
100+60+0+0=160
然而并没有什么可以整理的题目,只能说要抓紧开始练DP了
day4
T1 DP,T2虚树,T3欧拉回路板子,T4超强组合数
0+50+5+0=55
DP是一如既往不会
T2(树的重心)(出题人题解)
给定一棵 \(n\) 个节点的树,节点编号为 \(1\) 到 \(n\),根的编号为 \(1\)。
有 \(q\) 次询问,每次询问给定一个点集 \(S\)(即树上的若干节点),你需要找到该点集的重心。
重心定义为:一个节点是点集 \(S\) 的重心,当且仅当删除该节点后,每个连通块中属于点集 \(S\) 的节点数不超过 \(\lfloor \frac{|S|}{2} \rfloor\)。
注意,一个点集可能有多个重心,你只需输出其深度最小的一个即可。可以证明这样的重心是唯一的。

day5
T1思维,T2思维,T3分治,T4 DP
越打越菜了,连个T1黄题都写不出来了
T1(序列异或)
给一个长度为 \(n\) 的数组 \(a_1, a_2,\dots,a_n\)。
问有多少组满足条件的 \(b_1, b_2, b_3, b_4(1 ≤ b_1 <b_2 < b_3 < b_4 ≤ n)\) 满足:
\(a_{b_1} \operatorname{xor} a_{b_2} \operatorname{xor} a_{b_3} \operatorname{xor} a_{b_4}= 0\)
\(4 \leq n \leq 5000,0 \leq a_i \leq 1 \times {10}^6\)
- \(b_1 \operatorname{xor} b_2 \operatorname{xor} b_3 \operatorname{xor} b_4 \Longleftrightarrow b_1 \operatorname{xor} b_2 = b_3 \operatorname{xor} b_4\)
- 枚举 \(b_1,b_2\) 位置,然后看 \(b_2\) 后面有几对数的异或和等于 \(b_1 \operatorname{xor} b_2\),计入答案最后输出即可
- 时间复杂度 \(O(n^2)\) ,实现比较精妙,这里贴一下代码
code
#include<bits/stdc++.h>
using namespace std;
const int N=3e6+5;
int n,a[N],num[N],ans=0;
signed main()
{
cin>>n;
for(int i=1;i<=n;i++) cin>>a[i];
for(int i=1;i<=n;i++) for(int j=i+1;j<=n;j++) num[(a[i]^a[j])]++;//统计序列中所有异或和及对数
for(int i=1;i<=n;i++){//枚举b2
for(int j=i+1;j<=n;j++) num[(a[i]^a[j])]--;//把右边与b2能组成的所有异或和删去,那么剩下的异或和必然都在b2之右
for(int j=1;j<i;j++) ans+=num[(a[j]^a[i])];//(枚举b1)左侧能与b2组成的异或和全部枚举一遍计入答案
}
cout<<ans;
return 0;
}
day6
今天比较正常发挥,也不知道是不是因为开始总结自己之前5日浑浑噩噩的成绩缘故
T1 思维题,T2树形DP,T3思维+DS题,T4 DS题
T1(元素消除)
给定长为 \(n\) 的正整数序列 \(a\)。
你可以执行下面两种操作:
- 将任意一段长为 \(k\) 的连续区间中的 \(a_i\) 全部减 \(1\);
- 将某一个 \(a_i\) 减 \(r\)。
请判断能否经过若干次操作将 \(a_i\) 全部变为 \(0\)。
\(1 \leq n,k \leq 10^5 , 1 \leq r \leq 10^{18}\)
- 很显然的思路是先将所有操作1做完一遍后看看序列是否可以只用操作2全部消除
- 由于操作1的目标是要把剩下所有数都可以被操作2消除,即 \(a_i \equiv 0 (\operatorname{mod}\ p)\) ,所以我们从左到右依次枚举 \(i\) ,重复对 \(a_i\) 进行操作1 直到 \(a_i\operatorname{mod} p=0\) 接着再枚举下一个数,最后判断数组剩下的是否全为 \(p\) 的倍数
- 具体操作为先将 \(a_i\) 全部 \(\bmod p\) ,枚举操作数 \(i(1 \leq i < i+k-1 \leq n)\) ,对 \([i,i+k-1]\) 减去 \(a_i\) ,最后检查 \(\forall 1 \leq i \leq n,a_i \operatorname{mod} p=0\) ,若为真则为
Yes,反之为No - 时间复杂度 \(O(nk+k^2)\) 显然过不了
- 复杂度瓶颈在于暴力区间加减,注意到对 \(a_i\) 做的操作只会影响后面 \(k\) 个数,因此建一个队列,储存当前数所受的影响,每次向队列中加入当前点的影响同时删除队首点的影响即可
- 时间复杂度 \(O(n)\)

浙公网安备 33010602011771号