# Codeforces Round #630 (Div. 2)

### A. Exercising Walk

Code
/*
* Author:  heyuhhh
* Created Time:  2020/3/31 21:38:57
*/
#include <iostream>
#include <algorithm>
#include <cstring>
#include <vector>
#include <cmath>
#include <set>
#include <map>
#include <queue>
#include <iomanip>
#include <assert.h>
#define MP make_pair
#define fi first
#define se second
#define pb push_back
#define sz(x) (int)(x).size()
#define all(x) (x).begin(), (x).end()
#define INF 0x3f3f3f3f
#define Local
#ifdef Local
#define dbg(args...) do { cout << #args << " -> "; err(args); } while (0)
void err() { std::cout << '\n'; }
template<typename T, typename...Args>
void err(T a, Args...args) { std::cout << a << ' '; err(args...); }
template <template<typename...> class T, typename t, typename... A>
void err(const T <t> &arg, const A&... args) {
for (auto &v : arg) std::cout << v << ' '; err(args...); }
#else
#define dbg(...)
#endif
using namespace std;
typedef long long ll;
typedef pair<int, int> pii;
const int N = 1e5 + 5;

void run() {
int a, b, c, d; cin >> a >> b >> c >> d;
int x, y; cin >> x >> y;
int r1, c1, r2, c2; cin >> r1 >> c1 >> r2 >> c2;
int w = r2 - r1, h = c2 - c1;
if(w) {
int t = min(a / w, b / w);
a -= t * w, b -= t * w;
int tt = min(a, b);
a -= tt, b -= tt;
}
if(a > x - r1 || b > r2 - x) {
cout << "NO" << '\n';
return;
}
if(h) {
int t = min(c / h, d / h);
c -= t * h, d -= t * h;
int tt = min(c, d);
c -= tt, d -= tt;
}
if(c > y - c1 || d > c2 - y) {
cout << "NO" << '\n';
return;
}
cout << "YES" << '\n';
return;
}

int main() {
ios::sync_with_stdio(false);
cin.tie(0); cout.tie(0);
cout << fixed << setprecision(20);
int T; cin >> T;
while(T--) run();
return 0;
}


### B. Composite Coloring

Code
/*
* Author:  heyuhhh
* Created Time:  2020/3/31 22:01:11
*/
#include <iostream>
#include <algorithm>
#include <cstring>
#include <vector>
#include <cmath>
#include <set>
#include <map>
#include <queue>
#include <iomanip>
#include <assert.h>
#define MP make_pair
#define fi first
#define se second
#define pb push_back
#define sz(x) (int)(x).size()
#define all(x) (x).begin(), (x).end()
#define INF 0x3f3f3f3f
#define Local
#ifdef Local
#define dbg(args...) do { cout << #args << " -> "; err(args); } while (0)
void err() { std::cout << '\n'; }
template<typename T, typename...Args>
void err(T a, Args...args) { std::cout << a << ' '; err(args...); }
template <template<typename...> class T, typename t, typename... A>
void err(const T <t> &arg, const A&... args) {
for (auto &v : arg) std::cout << v << ' '; err(args...); }
#else
#define dbg(...)
#endif
using namespace std;
typedef long long ll;
typedef pair<int, int> pii;
const int N = 1000 + 5;

int n;
int a[N], col[N];
int primes[N], tot;
bool vis[N];

void init() {
for(int i = 2; i < N; i++) {
if(!vis[i]) primes[++tot] = i;
for(int j = i * i; j < N; j += i) vis[j] = true;
}
}

void run() {
cin >> n;
for(int i = 1; i <= n; i++) cin >> a[i];
vector <vector <int>> c, p;
c.resize(12); p.resize(n + 1);
for(int i = 1; i <= n; i++) {
for(int j = 1; j <= 11; j++) {
if(a[i] % primes[j] == 0) {
c[j].push_back(i);
p[i].push_back(j);
}
}
}
memset(col, -1, sizeof(col));
for(int i = 1; i <= 11; i++) {
for(auto it : c[i]) {
if(col[it] == -1) {
col[it] = i;
break;
}
}
}
for(int i = 1; i <= n; i++) if(col[i] == -1) col[i] = p[i][0];
map <int, int> mp; int num = 0;
for(int i = 1; i <= n; i++) {
if(!mp[col[i]]) mp[col[i]] = ++num;
col[i] = mp[col[i]];
}
cout << num << '\n';
for(int i = 1; i <= n; i++) cout << col[i] << " \n"[i == n];
}

int main() {
ios::sync_with_stdio(false);
cin.tie(0); cout.tie(0);
cout << fixed << setprecision(20);
init();
int T; cin >> T;
while(T--) run();
return 0;
}


### C. K-Complete Word

Code
/*
* Author:  heyuhhh
* Created Time:  2020/3/31 22:23:34
*/
#include <iostream>
#include <algorithm>
#include <cstring>
#include <vector>
#include <cmath>
#include <set>
#include <map>
#include <queue>
#include <iomanip>
#include <assert.h>
#define MP make_pair
#define fi first
#define se second
#define pb push_back
#define sz(x) (int)(x).size()
#define all(x) (x).begin(), (x).end()
#define INF 0x3f3f3f3f
#define Local
#ifdef Local
#define dbg(args...) do { cout << #args << " -> "; err(args); } while (0)
void err() { std::cout << '\n'; }
template<typename T, typename...Args>
void err(T a, Args...args) { std::cout << a << ' '; err(args...); }
template <template<typename...> class T, typename t, typename... A>
void err(const T <t> &arg, const A&... args) {
for (auto &v : arg) std::cout << v << ' '; err(args...); }
#else
#define dbg(...)
#endif
using namespace std;
typedef long long ll;
typedef pair<int, int> pii;
const int N = 2e5 + 5;

int n, k;
int cnt[N][26];
char s[N];

void run() {
cin >> n >> k;
cin >> (s + 1);
for(int i = 1; i <= n; i++) {
for(int j = 0; j < 26; j++) {
cnt[i][j] = 0;
}
}
for(int i = 1; i <= k; i++) {
for(int j = i; j <= n; j += k) {
++cnt[i][s[j] - 'a'];
}
}
int l = 1, r = k;
int ans = 0;
int d = n / k;
while(l < r) {
int res = INF;
for(int i = 0; i < 26; i++) {
res = min(res, 2 * d - cnt[l][i] - cnt[r][i]);
}
ans += res;
++l, --r;
}
if(l == r) {
int res = INF;
for(int i = 0; i < 26; i++) {
res = min(res, d - cnt[l][i]);
}
ans += res;
}
cout << ans << '\n';
}

int main() {
ios::sync_with_stdio(false);
cin.tie(0); cout.tie(0);
cout << fixed << setprecision(20);
int T; cin >> T;
while(T--) run();
return 0;
}


### D. Walk on Matrix

• 我们考虑诱导$$dp$$结果为$$0$$，此时最大值为$$k$$，这样方便构造。
• 注意到$$k$$$$a_{i,j}$$的取值范围，我们考虑$$n\geq 2,m\geq 2$$$$k>0$$的情况：现在得到最大的二进制为$$lim$$，最大权值为$$(lim*2)-1$$，那么直接构造$$a_{2,2}=k+lim,a_{1,2}=lim,a_{2,1}=a_{2,3}=a_{3,2}=k$$
• 按以上构造可以得出$$dp_{2,2}=lim$$，但是最终结果为$$0$$，因为$$lim\& k=0$$。但最大的答案应该是$$k$$
• $$n==1||m==1$$$$k=0$$的情况随便构造即可。

Code
/*
* Author:  heyuhhh
* Created Time:  2020/3/31 22:49:29
*/
#include <iostream>
#include <algorithm>
#include <cstring>
#include <vector>
#include <cmath>
#include <set>
#include <map>
#include <queue>
#include <iomanip>
#include <assert.h>
#define MP make_pair
#define fi first
#define se second
#define pb push_back
#define sz(x) (int)(x).size()
#define all(x) (x).begin(), (x).end()
#define INF 0x3f3f3f3f
#define Local
#ifdef Local
#define dbg(args...) do { cout << #args << " -> "; err(args); } while (0)
void err() { std::cout << '\n'; }
template<typename T, typename...Args>
void err(T a, Args...args) { std::cout << a << ' '; err(args...); }
template <template<typename...> class T, typename t, typename... A>
void err(const T <t> &arg, const A&... args) {
for (auto &v : arg) std::cout << v << ' '; err(args...); }
#else
#define dbg(...)
#endif
using namespace std;
typedef long long ll;
typedef pair<int, int> pii;
const int N = 1e5 + 5;

int k;
int a[4][4];

void run() {
cin >> k;
if(k == 0) {
cout << 1 << ' ' << 1 << '\n' << 0 << '\n';
return;
}
int lim = 1;
while(lim < 3e5) lim <<= 1;
lim >>= 2;
int MAX = (lim << 1) - 1;
cout << 3 << ' ' << 3 << '\n';
a[1][1] = MAX;
a[2][1] = k;
a[1][2] = lim;
a[2][2] = lim + k;
a[2][3] = a[3][2] = (MAX ^ lim);
a[3][3] = MAX;
for(int i = 1; i <= 3; i++) {
for(int j = 1; j <= 3; j++) {
cout << a[i][j] << ' ';
}   cout << '\n';
}
}

int main() {
ios::sync_with_stdio(false);
cin.tie(0); cout.tie(0);
cout << fixed << setprecision(20);
run();
return 0;
}


### E. Height All the Same

• 选择一个格子，令$$a_{i,j}+=2$$
• 选择两个相邻格子，让他们都加上$$1$$

• 从每个权值的奇偶性出发：操作$$1$$不会改变奇偶性，操作$$2$$则相当于一个“翻转”操作：$$0\rightarrow 1,1\rightarrow 0$$
• 那么问题等价于给定一个$$01$$矩阵，是否存在一种操作方案，使得所有数为$$0$$或者为$$1$$
• 那么有一个重要的观察：如果矩形中有偶数个$$0$$或者$$1$$，那么此时可以通过操作$$2$$使得所有数都相同。
• 现在考虑$$n\cdot m$$的奇偶性：
• $$n\cdot m$$为奇数，那么会发现不论怎么放，至少会存在偶数个数个$$0$$或者$$1$$。此时随便放即可。
• $$n\cdot m$$为偶数，$$0,1$$的个数必须都为偶数。若都为奇数，那么操作$$2$$并不会改变$$(奇，奇)$$的局面，因为通过操作$$2$$要么不改变$$0,1$$个数，要么使得个数增加/减少$$2$$，不改变$$(奇，奇)$$的局面。

Code
/*
* Author:  heyuhhh
* Created Time:  2020/3/31 23:52:41
*/
#include <iostream>
#include <algorithm>
#include <cstring>
#include <vector>
#include <cmath>
#include <set>
#include <map>
#include <queue>
#include <iomanip>
#include <assert.h>
#define MP make_pair
#define fi first
#define se second
#define pb push_back
#define sz(x) (int)(x).size()
#define all(x) (x).begin(), (x).end()
#define INF 0x3f3f3f3f
#define Local
#ifdef Local
#define dbg(args...) do { cout << #args << " -> "; err(args); } while (0)
void err() { std::cout << '\n'; }
template<typename T, typename...Args>
void err(T a, Args...args) { std::cout << a << ' '; err(args...); }
template <template<typename...> class T, typename t, typename... A>
void err(const T <t> &arg, const A&... args) {
for (auto &v : arg) std::cout << v << ' '; err(args...); }
#else
#define dbg(...)
#endif
using namespace std;
typedef long long ll;
typedef pair<int, int> pii;
const int N = 1e5 + 5, MOD = 998244353, inv2 = (MOD + 1) >> 1;
int qpow(ll a, ll b) {
ll res = 1;
a %= MOD;
while(b) {
if(b & 1) res = res * a % MOD;
a = a * a % MOD;
b >>= 1;
}
return res;
}

void run() {
ll n, m, L, R;
cin >> n >> m >> L >> R;
int even = R / 2, odd = (R + 1) / 2;
even -= (L - 1) / 2, odd -= L / 2;
int res = qpow(even + odd, n * m);
if((n * m) & 1) cout << res << '\n';
else {
res += qpow(max(even, odd) - min(even, odd), n * m);
res %= MOD;
res = 1ll * res * inv2 % MOD;
cout << res << '\n';
}
}

int main() {
ios::sync_with_stdio(false);
cin.tie(0); cout.tie(0);
cout << fixed << setprecision(20);
run();
return 0;
}


$$dp[i][2]$$表示前$$i$$个数，放置了奇数个/偶数个奇数/偶数，不妨考虑放置的是奇数。那么转移为：

• $$dp[i][1]=dp[i-1][0]\cdot O+dp[i-1][0]\cdot E$$;
• $$dp[i][0]=dp[i-1][1]\cdot O+dp[i-1][0]\cdot E$$

### F. Independent Set

$\sum_{E'\not ={\emptyset}\subset E}w(G'[E'])$

• 考虑对每个结点进行染色，$$dp$$时枚举每条边是否断开。显然可以分情况讨论：

• $$u$$不染色时，那么边$$(u,v)$$无论是否断开，都可以从$$v$$染色或者不染色两种情况进行转移。
• $$u$$染色时，若边$$(u,v)$$断开，那么$$v$$可染色也可不染色；边$$(u,v)$$没有断开，那么$$v$$不能染色。
• 因为要从边生成子图中找独立集，也就是每个染色的点至少会有一条边与之相连。那么上述两种情况断开时儿子结点都可以染色，但要排除儿子结点为单独一个点的情况。

• $$dp[u][2]$$$$u$$结点为根节点时，所有儿子结点都没有边与之相连的情况。显然这种情况会被算入$$dp[u][1],dp[u][0]$$

• 那么我们只需要在上述转移中将$$dp[v][2]$$$$dp[v][1]$$中减去即可。

Code
/*
* Author:  heyuhhh
* Created Time:  2020/4/1 20:29:05
*/
#include <iostream>
#include <algorithm>
#include <cstring>
#include <vector>
#include <cmath>
#include <set>
#include <map>
#include <queue>
#include <iomanip>
#include <assert.h>
#define MP make_pair
#define fi first
#define se second
#define pb push_back
#define sz(x) (int)(x).size()
#define all(x) (x).begin(), (x).end()
#define INF 0x3f3f3f3f
#define Local
#ifdef Local
#define dbg(args...) do { cout << #args << " -> "; err(args); } while (0)
void err() { std::cout << '\n'; }
template<typename T, typename...Args>
void err(T a, Args...args) { std::cout << a << ' '; err(args...); }
template <template<typename...> class T, typename t, typename... A>
void err(const T <t> &arg, const A&... args) {
for (auto &v : arg) std::cout << v << ' '; err(args...); }
#else
#define dbg(...)
#endif
using namespace std;
typedef long long ll;
typedef pair<int, int> pii;
const int N = 3e5 + 5, MOD = 998244353;

int n;
vector <int> G[N];
int dp[N][3];

void dfs(int u, int fa) {
dp[u][0] = dp[u][1] = dp[u][2] = 1;
for(auto v : G[u]) if(v != fa) {
dfs(v, u);
dp[u][0] = 1ll * dp[u][0] * (2ll * dp[v][0] + 2 * dp[v][1] - dp[v][2] + MOD) % MOD;
dp[u][1] = 1ll * dp[u][1] * (2ll * dp[v][0] + dp[v][1] - dp[v][2] + MOD) % MOD;
dp[u][2] = 1ll * dp[u][2] * (1ll * dp[v][0] + dp[v][1] - dp[v][2] + MOD) % MOD;
}
}

void run() {
cin >> n;
for(int i = 1; i < n; i++) {
int u, v; cin >> u >> v;
G[u].push_back(v);
G[v].push_back(u);
}
dfs(1, 0);
int ans = ((ll)dp[1][0] + dp[1][1] - dp[1][2] + MOD - 1) % MOD;
cout << ans << '\n';
}

int main() {
ios::sync_with_stdio(false);
cin.tie(0); cout.tie(0);
cout << fixed << setprecision(20);
run();
return 0;
}

posted @ 2020-04-01 14:27  heyuhhh  阅读(721)  评论(0编辑  收藏  举报