专栏文章
题解:AT_arc171_d [ARC171D] Rolling Hash
AT_arc171_d题解参与者 1已保存评论 0
文章操作
快速查看文章及其快照的属性,并进行相关操作。
- 当前评论
- 0 条
- 当前快照
- 1 份
- 快照标识符
- @miod7e1s
- 此快照首次捕获于
- 2025/12/02 17:17 3 个月前
- 此快照最后确认于
- 2025/12/02 17:17 3 个月前
题目大意
给定整数 , 满足 是质数,。对于序列 ,定义 的值为
给定 对整数()(),请问是否存在长度为 的序列 满足:对每一个 (),都有
。
思路
如果学过字符串哈希,可以很快写出区间哈希值:
中间的式子显然不好做,因为 不容易维护。但是后面的形式很容易啊,因为 必不可能为 ,哈希值为 相当于。
在 意义下,哈希值的下一位是几都可以构造出来,因为下一位可以取遍 的每个数。所以题意转化成要给 每个点赋 的权值, 权值为 ,然后给你 条边,你要保证边连接的两个点权值不同。
- 当 时,颜色数不少于点数,一定有解。
- 当 时,等价于图染色,不能多项式。
设 表示将点 中点的导出子图染色,最少用几种颜色。每次开一个新颜色,染成新颜色的点得是一个独立集 ,则:
其中 为独立集。
代码
CPP#include <bits/stdc++.h>
using namespace std;
#define int long long
const int N = 17;
int p, b, n, m;
int g[1 << N], G[N][N], f[1 << N];
signed main(){
cin >> p >> b >> n >> m;
for (int i = 1; i <= m; i++){
int l, r;
cin >> l >> r;
G[l - 1][r] = 1;
G[r][l - 1] = 1;
}
if (p > n){
cout << "Yes" << "\n";
return 0;
}
const int U = (1 << (n + 1)) - 1;
for (int i = 0; i <= U; i++){
g[i] = 1;
for (int j = 0; j <= n; j++){
if ((i >> j) & 1){
for (int k = j + 1; k <= n; k++){
if ((i >> k) & 1){
if (G[j][k]) g[i] = 0;
}
}
}
}
}
memset(f, 0x3f, sizeof f);
f[0] = 0;
for (int i = 1; i <= U; i++){
for (int j = i; j; j = (j - 1) & i){
if (g[j]){
f[i] = min(f[i], f[i ^ j] + 1);
}
}
}
if (f[U] <= p) cout << "Yes" << "\n";
else cout << "No" << "\n";
return 0;
}
相关推荐
评论
共 0 条评论,欢迎与作者交流。
正在加载评论...