2024年06月随便做做
The 2nd Universal Cup. Stage 17: Jinan
为了参加省赛打的模拟。
打了八个题,稳稳金牌。
E. I Just Want... One More...
考虑如何计数,因此考虑方案的等价条件。
一条边满足要求,当且仅当原图存在一种最大匹配,使得这条边的两个顶点都不在匹配中。
而上述条件,实际上等价于两个顶点各自满足:存在一种最大匹配,使得这个点不在匹配中。
证明考虑广义 Hall 定理。
于是我们只需要判断二分图匹配的非必经点即可。实际上跑出最大流后,我们从源点出发走剩余流量不为 \(0\) 的边(包含反向边),可以走到的左部点是非必经点;从汇点出发走剩余流量为 \(0\) 的边,可以走到的右部点也是非必经点,与前者同理,相当于对称。前者这样的根据是,如果这个点向汇点连一条容量为 \(1\) 的边,那么一定可以使最大流 \(+1\),因此原本的匹配中可以没有它。
因此分别求出左部和右部中的非必经点数量,再乘起来即可。
但是实际上可以直接考虑网络流增广路理解,过程几乎一摸一样,但是不需要广义 Hall 定理,我又想复杂了 qwq。
L. Ticket to Ride
考虑设计 dp 转移式 \(f(i,j)\) 表示前 \(i\) 条线已经考虑完成,其中有 \(j\) 条线没有被覆盖。
我们可以依次枚举 \(j\),做如下 DP 转移:
如果正在考虑 \(i\) 位置,记 \(m_t\) 表示 \(1\) 到 \(t\) 之间的能作为 \(i'\) 的最优选择。这个 \(m_t\) 一定是随着 \(t\) 变大单调不降的。
每次以 \(j\) 作为 \(r\) 枚举奖励区间的 \(l\),将 \(1\) 到 \(l-1\) 的贡献加上奖励权值,更新 \(m\) 即可,很明显因为 \(m\) 中每一段都指向一个位置考虑是否最大,这中间不会有段的分裂,只有合并。
以段为单位看,势能分析知段的合并和更新次数为 \(O(n)\)。
具体可以使用并查集加链表,更新 \(f(1,j)\cdots f(n,j)\) 的时间复杂度为 \(O(n\alpha (n))\) ,总时间复杂度为 \(O(n^2\alpha (n)+nm)\)。
M. Almost Convex
其他的不用说,考虑对于两个特殊点和一个点集,在点集中选择一个点与两个特殊点构成三角形,且三角形内部不包含点集中的其他点,问点集中有多少个这样的点。
实际上考虑这个点与两个特殊点构成的两个角,一个点满足要求等价于它的两个角度不存在偏序大于另外一个点的两个角度的情况。
The 2nd Universal Cup. Stage 22: Hangzhou
为了准备省赛打的模拟。
打了 6 个 题,大概是银牌线。
B. Festival Decorating
把每个颜色的位置的补集放在在 bitset 上,可以得到一个空间和事件复杂度均为 \(O(\frac{n^2}{w})\) 的显然方法,但是空间过不去,因此考虑优化空间复杂度。
考虑对于出现次数 \(>\sqrt n\) 的颜色开 bitset,而出现次数 \(\le\sqrt n\) 的情况直接在每次遇到的时候暴力求出,这样时间复杂度为 \(O(\frac{n^2}w+\frac{n\sqrt n}{w})=O(\frac{n^2}{w})\),而空间复杂度为 \(O(\frac{n\sqrt n}w)\)。
C. Yet Another Shortest Path Query
易知平面图的边数不超过 \(3n-6\),因此度数最小的点的度数一定不超过 \(5\),我们做 \(n\) 次操作,每次操作把当前图中度数最小的点删去。
记 \(t(v)\) 表示 \(v\) 点删除的时间。我们把无向边 \((u,v)\) 拆成两条有向边,不妨设 \(t(u) < t(v)\),则 L 类边为 \(u\to v\),R 类边为 \(v\to u\)。
显然一个点只能作为最多 \(5\) 条 L 边的起点,\(5\) 条 R 边的终点。
发现边数 \(k\le 3\) 的要求可以是询问变为分类讨论。
- 依次经过:L 或 R,显然可做。
- 依次经过:LR 或 RL 或 LL 或 RR,显然也可做。
- 依次经过:LLR 或 LRL 或 LLL 或 LRR,枚举第一个 L 边,转换成 \(5\) 个子问题。
- 依次经过:LRR 或 RLR 或 LLR 或 RRR,枚举最后一个 R 边,转换成 \(5\) 个子问题。
没有其他的情况,因此将问题离线。注意时间和空间限制,因此必须要做到精妙的实现,目前这份提交是 QOJ 最优解。
E. Period of a String
没什么可说的,重在实现。
H. Sugar Sweet II
注意到将事件的 \(b_i\) 按 \(b_i\to i\) 建出图,发现是一个外向基环树森林。如果只有树的情况,实际上要分类讨论。
设 \(p_u\) 表示 \(u\) 点在事件 \((u,b_u)\) 发生时满足条件的概率。记 \(v\) 为 \(u\) 深度最大的祖先(可以是自己),使得 \(p_u=1\),即直接有 \(a_u<a_{b_u}\),这时应有:
因为从 \(v\) 到 \(u\) 的所有点对应的事件必须按照从 \(v\) 到 \(u\) 的相对顺序发生,概率为 \(\frac{1}{(dep_u-dep_v+1)!}\)。
考虑在基环树上,则是找到到他距离最近的 \(v\),dfs 即可。
K. Card Game
考虑一个答案的函数 \(ans(l,r)\),实际上应该有:
因为要离线,因此这个可以使用主席树的合并和永久化标记来实现。
The 2024 Sichuan Provincial Collegiate Programming Contest
省赛的题目真的纯降智,感觉我们的准备一点用都没有。最后作为打星队伍做了 9 题,获得了第 7 名。剩下没做的题目是 BDI,感觉都很可惜。
以下是我想出的题目。
A. Reverse Pairs Coloring
考虑没有 \(a_i>a_j\) 的限制,则,并把每一行行内连通的块看成一个点,则网格图从上往下构成了一棵树。考虑 \(a_i>a_j\) 的要求实际上是把树上的一些点砍掉,我们可以倒着扫,遇到砍掉的部分把这部分结算计入答案即可。但是因为前面也有砍掉的部分,因此需要用树状数组记录砍掉部分会有多少点结算。
F. Isoball: 2D Version
相当于判断一条射线是否与矩形有交。
G. Function Query
可以利用 trie 找到两个最大的 \(i\),分别满足 \((a\oplus x_i)<b\) 和 \((a\oplus x_i)>b\),这两个中间较小的那个就是答案。
等于的情况要特殊判断。
J. Roman Numberals
简单数位 DP 即可,以当前位为 \(1\) 往前记 \(1000\)。
L. Beef Tripe in Soup Pot?
签到题。
The 2nd Universal Cup. Stage 09: Qinhuangdao
A. Make SYSU Great Again I
考虑按阶梯放置:
1200
0340
0056
8007
每行每列的 gcd 都是 \(1\)。
B. Yet Another Subsequence Problem
这两个月目前做到的最好的题目!
考虑相当于画一条 \((0,0)\) 到 \((a,b)\) 的线。我们从 \((0,0)\) 开始默认向右走并填 \(0\),如果当前的 \((x,y)\) 在线的严格下方,则向上走并填 \(1\)。
考虑:
- 若 \(a\le b\),则一次向右的移动一定会跟 \(\left\lfloor\frac{b}{a}\right\rfloor\) 次向上的移动,如果发现不足 \(\left\lfloor\frac{b}{a}\right\rfloor\) 次,那么在这次向右的移动的前一次移动一定是不合法。
- 若 \(a>b\),则一次向上的移动一定会跟 \(\left\lfloor\frac{a-1}{b}\right\rfloor\) 次向右的移动。这里的减一实际上有点绕,在 \(b\) 整除 \(a\) 之后,如果这个向上移动的起点的左边的点恰好是一个在线上的点,那么这次向上移动之后再向右移动 \(\frac{a}{b}-1\) 次,会再次到达线上的整点,而如果这个整点是结束的位置,那么将只会跟 \((\frac{a}{b}-1=\lfloor\frac{a-1}{b}\rfloor)\) 次向右移动,除此之外其他情况下的次数为 \(\lfloor\frac{a}{b}\rfloor\),也就是 \(\lfloor\frac{a-1}{b}\rfloor\)。
考虑是否可以将问题缩小规模,因此将一定会跟在某次移动之后的一串连续相同字符合在一起当作新的元素。
考虑已知 \(01\) 序列后可以使用矩阵求出答案,对于 \(0\) 和 \(1\) 分别有矩阵 \(M_0,M_1\),记答案为:\(f(a,b,M_0,M_1)\)。
- \(a\le b,f(a,b,M_0,M_1)=f\left(a,b-a\lfloor\frac{b}{a}\rfloor,M_0M_1^{\lfloor\frac{b}{a}\rfloor},M_1\right)\)。
- \(a>b,f(a,b,M_0,M_1)=f\left(a-b\lfloor\frac{a-1}{b}\rfloor,b,M_0,M_1M_0^{\lfloor\frac{a-1}{b}\rfloor}\right)\)。
会发现这样缩小是对的,以 \(a\le b\) 时为例,向右移动之后会向上移动数次,之后发现当前位置与线的铅垂差与执行这些移动前的铅垂差相对变化了 \(\frac{b-a\lfloor\frac{b}{a}\rfloor}{a}\)(原本为 \(\frac b a\)),而每次向右移动都会这样,向上移动则不用考虑,因此如果把这数次向上移动合并进向右移动中,相当于新的子问题中,向右移动一步就会使铅垂差变化 \(\frac{b-a\lfloor\frac{b}{a}\rfloor}{a}\),我们把这个直接当成新的线的斜率即可,同时因为总移动次数的要求,所以得到上述的递归。
这样类似于类欧的递归,时间复杂度 \(O(\log_2 a)\)。
D. Yet Another Coffee
简单签到。
E. Coloring Tape
首先的一点是对于当前列的色带的表示法,实际上我们可以在列与列之间的线上记录状态,具体可以记录有在哪些位置会有刷子跨过线。当然因为会有刷子停下来的情况,因此我们还要做一个二进制的后缀和,可以用 sosdp 做到 \(O(n2^n)\)。
但是如果我们要考虑刷的情况只能 dfs,直觉上这样的转移是很少的,果然就算 \(n\) 最大时转移也只有 \(10^5\) 左右。
于是就这样转移完了。
难度标成全场第二难的题目,是不是太水了?
F. Mystery of Prime
利用波利尼亚克猜想转化成奇偶问题。
G. Path
简单签到。
H. Quake and Rebuild
考虑分块+根号分治。分块后对于每个点记录 \(nex\) 表示第一个异侧祖先,维护是简单的,可以记录每个块的修改量 \(\Delta\),如果 \(\Delta < \sqrt n\) 则直接重构,否则 \(nex_i=\max (fa_i-\Delta, 1)\)。
然后建虚树则可以从后往前扫,分类讨论:
-
如果当前块内没有点,则跳过;
-
如果不存在两个点的 \(nxt\) 相同,则它们都不会在块内出现 lca,直接跳到 \(nxt\) 即可(注意同时维护跳的步数加在答案上);
-
如果存在两个点的 \(nxt\) 相同,则直接 \(O(\sqrt n)\) 扫一遍块内,发现 \(O(\sqrt n)\) 的时间可以使点数至少 \(-1\),易知总时间复杂度为 \(O(\sqrt n\sum k)\)。
因此总共的时间复杂度为 \(O((n+m+\sum k)\sqrt n)\),就结束了。
I. Phony
对除以 \(t\) 的不同的答案和余数分段,可以平衡树、线段树等等。
J. Keyi LIkes Reading/Book
子集 DP 即可。
M. Inverted
可以在 DP 时考虑 \(u\) 和 \(u+n\) 的连通状况决定连边,因此 \(f(u,0/1)\) 表示只考虑 \(u\) 和 \(u\) 的子树内,\(u\) 和 \(u+n\) 是否连通,就可 \(O(n)\) 求出固定图的答案。
Miscellaneous
[CCPC Finals 2021] H. Harie Progamming Contest
先染色成二分图,发现异侧的情况和上边 I just want... One more... 这题一模一样。
因此考虑同侧的情况,对于无序点对 \((u,v)\) 原本的要求等价于在残量网络中以 \(s\) 为源,找两条没有边相交的路径,终点分别为 \(u,v\)。
可以使用支配树,但是问题是没有边相交,如果有重复的点就不用管,因此把边拆出点,同时将点变成两个,跑支配树即可。
我忘记拆点也过了,不知道是数据水还是图的性质。
Submission #267176842 - Codeforces
Pollard-Rho
int ae[7] = {2, 325, 9375, 28178, 450775, 9780504, 1795265022};
inline bool MR (int p){
if (p < 2)
return false;
if (p < 4)
return true;
static int d, r; d = p - 1, r = 0;
while (! (d & 1))
d >>= 1, ++ r;
for (int i = 0, a, x, T;i < 7;++ i){
a = ae[i] % p;
if (a == 1 || a == p - 1 || a == 0)
continue;
x = power (a, d, p);
if (x == 1)
continue;
for (T = r;T --;){
if (x == p - 1)
break;
x = (i128) x * x % p;
}
if (T < 0)
return false;
}
return true;
}
inline int PR (int p){
static int s, t, c, i, ed, prd, d;
s = t = 0, c = mtrand () % (p - 1) + 1;
for (ed = 1;;ed <<= 1){
prd = 1, s = t;
for (i = 1;i <= ed;++ i){
t = ((i128) t * t + c) % p;
prd = (i128) prd * abs (t - s) % p;
if (i % 127 == 0){
d = gcd (prd, p);
if (d > 1)
return d;
}
}
d = gcd (prd, p);
if (d > 1)
return d;
}
return - 1;
}
Codeforces 1218A BubbleReactor
可以 \(O(n)\) 求出树的情况,在环上跑区间 DP 即可。
Submission #267178302 - Codeforces
QOJ #4094. 히스토그램
建出笛卡尔树,然后树上做李超线段树合并即可。但是注意特殊的:[[][]] 情况要使用凸包合并解决。总之非常麻烦。
因为写完李超线段树合并之后发现还有 \(O(n)\) 维护闵可夫斯基和,于是粘了一份学长的代码/dk。
本文作者:saubguiu
本文链接:https://www.cnblogs.com/imcaigou/p/18249252
版权声明:本作品采用知识共享署名-非商业性使用-禁止演绎 2.5 中国大陆许可协议进行许可。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步