题解:AT_arc171_d [ARC171D] Rolling Hash
liborui0000 · · 题解
题目大意
给定整数
hash(X) \equiv \sum_{i = 1}^{n} x_{i} B^{n - i}\pmod P
给定
hash((A_{L_{i} } ,A_{L_{i} + 1 },\dots , A_{R_{i} })) = 0 。
思路
如果学过字符串哈希,可以很快写出区间哈希值:
Hash_{l, r} = Hash_{1, r} − Hash_{1, l - 1}×B^{r - l + 1} = (Hash_{l, n} − Hash_{r + 1,n}) × B^{r - n}
中间的式子显然不好做,因为
在
- 当
P > n 时,颜色数不少于点数,一定有解。 - 当
P ≤ n 时,等价于图染色,不能多项式。
设
f_{S} = min(_{T\subseteq S}f_{S - T} + 1 )
其中
如果
代码
#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;
}