2023杭电多校第一场补题报告 1002 1005 1009 1012
1002 City Upgrading (hdu.edu.cn)
思路
直接上树形dp,比较麻烦的是需要考虑父节点的影响,其他比较模板。
代码
#include <bits/stdc++.h>
#define int long long
#define endl '\n'
#define IOS ios::sync_with_stdio(0), cin.tie(0), cout.tie(0)
#define fi first
#define sc second
using namespace std;
const int INF = 0x3f3f3f3f3f3f3f3f;
const int N = 2e5 + 10;
const int mod = 1e9 + 7;
typedef pair<int, int> PII;
int n;
int a[N];
vector<int> g[N];
int sc[N];
int dp[N][10]; // dp[i][0] 0被父亲覆盖,1被儿子覆盖,2被自己覆盖
void dfs(int u, int f) {
dp[u][0] = 0;
dp[u][1] = 0;
dp[u][2] = sc[u];
int ok = 0;
for (auto v : g[u]) {
if (v != f) {
dfs(v, u);
dp[u][0] += min(dp[v][1], dp[v][2]);
dp[u][1] += min(dp[v][1], dp[v][2]);
// cout << "###" << dp[v][1] << " " << dp[v][2] << endl;
if (dp[v][2] <= dp[v][1]) ok = 1;
dp[u][2] += min({dp[v][0], dp[v][1], dp[v][2]});
}
}
// cout << dp[2][1] << endl;
if (ok == 0) {
int mi = INF;
int id = -1;
for (auto v : g[u]) {
if (v != f) {
int d = dp[v][2] - dp[v][1];
if (d < mi) {
mi = d;
id = v;
}
}
}
dp[u][1] += mi;
}
}
void solve() {
int n;
cin >> n;
for (int i = 1; i <= n; i++) {
g[i].clear();
dp[i][0] = dp[i][1] = dp[i][2] = INF;
cin >> sc[i];
}
for (int i = 0; i < n - 1; i++) {
int x, y;
cin >> x >> y;
g[x].push_back(y);
g[y].push_back(x);
}
dfs(1, 0);
// for(int i = 1;i <= n;i++){
// cout << dp[i][0] << " " << dp[i][1] << " " << dp[i][2] << endl;
// }
cout << min(dp[1][1], dp[1][2]) << "\n";
}
signed main() {
IOS;
int t = 1;
cin >> t;
for (int i = 1; i <= t; i++) {
solve();
}
}
1005 Cyclically Isomorphic (hdu.edu.cn)
思路
因为所有字符串在循环意义上的字典序最小应该是一样的,所以预处理出来所有字符串的字典序最小排列,然后直接对比即可。
代码
#include <bits/stdc++.h>
#define int long long
#define endl '\n'
#define IOS ios::sync_with_stdio(0), cin.tie(0), cout.tie(0)
#define fi first
#define sc second
using namespace std;
const int INF = 0x3f3f3f3f3f3f3f3f;
const int N = 1e6 + 10;
const int mod = 1e9 + 7;
typedef pair<int, int> PII;
int n, m, d;
int a[N];
void solve() {
cin >> n >> m;
vector<string> st(n + 10);
for (int i = 1; i <= n; i++) {
string s;
cin >> s;
string tmp = s;
for (int j = 0; j < m; j++) {
s = s + s[0];
s.erase(s.begin());
tmp = min(tmp, s);
}
st[i] = tmp;
}
int q;
cin >> q;
while (q--) {
int x, y;
cin >> x >> y;
if (st[x] == st[y])
cout << "Yes\n";
else
cout << "No\n";
}
}
signed main() {
IOS;
int t = 1;
cin >> t;
for (int i = 1; i <= t; i++) {
solve();
}
}
1009 Assertion (hdu.edu.cn)
思路
直接抽屉原理,但是貌似编译器原因用除法会T,改成乘法ac了。
代码
#include <bits/stdc++.h>
#define int long long
#define endl '\n'
#define IOS ios::sync_with_stdio(0), cin.tie(0), cout.tie(0)
#define fi first
#define sc second
using namespace std;
const int INF = 0x3f3f3f3f3f3f3f3f;
const int N = 1e6 + 10;
const int mod = 1e9 + 7;
typedef pair<int, int> PII;
int n, m, d;
int a[N];
void solve() {
cin >> n >> m >> d;
if (d == 0) {
cout << "Yes\n";
return;
}
if ((d - 1) * n + 1 <= m)
cout << "Yes\n";
else
cout << "No\n";
}
signed main() {
IOS;
int t = 1;
cin >> t;
for (int i = 1; i <= t; i++) {
solve();
}
}
1012 Play on Tree (hdu.edu.cn)
思路
首先求出来sg函数(比较典就是所有子节点sg函数+1的异或和),然后再换根dfs跑一遍计数即可。
代码
#include <algorithm>
#include <cmath>
#include <cstdio>
#include <cstring>
#include <deque> //
#include <fstream>
#include <iostream>
#include <map> //
#include <queue> //队列
#include <set> //
#include <stack> //栈
#include <string>
#include <vector> //向量
#define int long long
#define endl '\n'
#define IOS ios::sync_with_stdio(0), cin.tie(0), cout.tie(0)
#define fi first
#define sc second
using namespace std;
const int INF = 0x3f3f3f3f3f3f3f3f;
const int N = 1e6 + 10;
const int mod = 1e9 + 7;
typedef pair<int, int> PII;
int n;
int a[N];
int qpow(int a, int b) {
int ans = 1, base = a;
while (b) {
if (b & 1) ans = ans * base % mod;
base = base * base % mod;
b >>= 1;
}
return ans % mod;
}
int sg[N], sg2[N];
vector<int> g[N];
void dfs(int u, int f) {
sg[u] = 0;
for (auto v : g[u])
if (v != f) {
dfs(v, u);
sg[u] ^= (sg[v] + 1);
}
}
int ans = 0;
void dfs2(int u, int f) {
for (int v : g[u]) {
if (v != f) {
sg2[v] = sg[v] ^ ((sg2[u] ^ (sg[v] + 1)) + 1);
dfs2(v, u);
}
}
}
void solve() {
int n;
cin >> n;
ans = 0;
for (int i = 1; i <= n; i++) {
g[i].clear();
sg[i] = 0;
}
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);
sg2[1] = sg[1];
dfs2(1, 0);
for (int i = 1; i <= n; i++)
if (sg2[i]) ans++;
cout << ans * qpow(n, mod - 2) % mod << "\n";
}
signed main() {
IOS;
int t = 1;
cin >> t;
for (int i = 1; i <= t; i++) {
solve();
}
}