2026.7.29 图论
A
解析
首先可以肯定的是一定有一种答案的d是小于m的
那么一种合法的匹配方式就是一个A的长为d的后缀和一个B的长为d的前缀匹配,一个A的后缀与B的前缀匹配,如图(实线为n个串,虚线为前后缀)

,那么对于一个固定的d,我们可以用哈希把一样的串压成一个点,然后连A的前缀->后缀,B的后缀->前缀,如果合法,那么就会有一条欧拉回路(如图,连线表示相同重合为一个点),直接找即可,复杂度 \(O(nm)\)
B
C
解析
差分约束
令 \(S_i\) 为左右括号差的前缀和,那么有 \(\forall S_i\ge 0\ , -1\le S_i-S_{i-1}\le 1 , S_0=S_n=0\),加上限制 \(S_r-S_{l-1}=c\),跑SPFA即可
启发
- \(a=b \Leftrightarrow a\le b \ \land a\ge b\),可以将相等转化为差分约束,反着来看也可以用来证明相等
- 递归的SPFA,好像会快一些不会被卡
bool spfa(int u){
vis[u]=1;
for(auto t:e[u]){
int v=t.first,w=t.second;
if(dis[v]>dis[u]+w){
dis[v]=dis[u]+w,cnt[v]=cnt[u]+1;
if(cnt[v]>n+1) return 0;
if(vis[v]||!spfa(v)) return 0;
}
}
vis[u]=0;
return 1;
}
D
解析
首先先考虑只有一条路的时候,将k均摊一定是最优的(证明显然:同一条边的收益会不断变小)
再考虑有两条路的时候,发现唯一的不同是有重边
显然重边只有一段,那么我们就可以用01BFS求一个全源最短路,然后暴力的枚举连续段的端点,算出不同长度重边对应的最小非重边,然后三分即可
启发
01BFS可以 \(O(n^2)\) 处理全源最短路(边权均为1时)
E
解析
显然二进制拆分
考虑二进制意义下一个数比比另一个数大,当且仅当两数公共前缀(可以为空)的下一位一个是1一个是0
因为是按位与,所以每次选取公共前缀和后一位作为答案即可(这样一定是要求位数最少的),边权中包含答案的才留下来,并查集维护连通性即可(注意位运算要写成1ll<<i)

浙公网安备 33010602011771号