題目鏈接
Codeforces - 1067A
看完轉移方程自己碼了出來,最後有個初始化的地方沒寫好卡了一下,還好給的時間和空間夠多,卡了過去。
代碼:
#include <bits/stdc++.h>
#define mst(a,b) memset(a,b,sizeof(a))
#define ALL(x) x.begin(),x.end()
#define pii pair<int,int>
#define eps 1e-6
#define debug(a) cout << #a": " << a << endl;
#define eularMod(a, b) a < b ? a : a % b + b
inline int lowbit(int x){ return x & -x; }
const int N = 1e5 + 10;
const int mod = (int) 998244353;
const int INF = 0x3f3f3f3f;
const long long LINF = (1LL << 62);
typedef long long LL;
typedef unsigned long long ULL;
const double PI = acos(-1.0);
using namespace std;
int n;
LL dp[N][205][3], sum[205][3], suf[205][3];
int v[N];
void getSum (int pos) {
for (int i = 1; i <= 200; i++) {
sum[i][0] = (sum[i - 1][0] + dp[pos][i][0]) % mod;
sum[i][1] = (sum[i - 1][1] + dp[pos][i][1]) % mod;
sum[i][2] = (sum[i - 1][2] + dp[pos][i][2]) % mod;
}
}
void getSuf (int pos) {
for (int i = 200; i >= 1; i--) {
suf[i][0] = (suf[i + 1][0] + dp[pos][i][0]) % mod;
suf[i][1] = (suf[i + 1][1] + dp[pos][i][1]) % mod;
suf[i][2] = (suf[i + 1][2] + dp[pos][i][2]) % mod;
}
}
void update (int i, int j) {
dp[i][j][0] = (sum[j - 1][0] + sum[j - 1][1] + sum[j - 1][2]) % mod;
dp[i][j][1] = (dp[i - 1][j][0] + dp[i - 1][j][1] + dp[i - 1][j][2]) % mod;
dp[i][j][2] = (suf[j + 1][1] + suf[j + 1][2]) % mod;
}
// 0 表示 v[i - 1] < v[i]
// 1 表示 v[i - 1] == v[i]
// 2 表示 v[i - 1] > v[i]
int main() {
#ifdef LOCAL
freopen("in.txt", "r", stdin);
// freopen("out.txt","w",stdout);
#endif
scanf("%d", &n);
for (int i = 1; i <= n; i++) {
scanf("%d", &v[i]);
}
if (v[1] == -1) {
for (int i = 1; i <= 200; i++) {
dp[1][i][0] = 1;
}
} else {
dp[1][v[1]][0] = 1;
}
getSum(1);
getSuf(1);
for (int i = 2; i <= n; i++) {
if (v[i] == -1) {
for (int j = 1; j <= 200; j++) {
update(i, j);
}
} else {
update(i, v[i]);
}
mst(sum, 0);
mst(suf, 0);
getSum(i);
getSuf(i);
}
LL ans = 0;
for (int i = 1; i <= 200; i++) {
ans = (ans + dp[n][i][2] + dp[n][i][1]) % mod;
}
printf("%lld\n", ans);
return 0;
}
Codeforces - 1067B
題意有點繞,一開始讀不懂第二個條件,以爲是葉子節點的父節點至少有 3 個孩子就可以,後面才知道是一層一層的刪都要滿足葉子節點的父節點至少有 3 個孩子,我的做法是找直徑的終點,然後 dfs 一下檢查是否符合條件。
代碼:
#include <bits/stdc++.h>
#define mst(a,b) memset(a,b,sizeof(a))
#define ALL(x) x.begin(),x.end()
#define pii pair<int,int>
#define eps 1e-6
#define debug(a) cout << #a": " << a << endl;
#define eularMod(a, b) a < b ? a : a % b + b
inline int lowbit(int x){ return x & -x; }
const int N = 1e5 + 10;
const int mod = (int) 998244353;
const int INF = 0x3f3f3f3f;
const long long LINF = (1LL << 62);
typedef long long LL;
typedef unsigned long long ULL;
const double PI = acos(-1.0);
using namespace std;
int n, k;
int deg[N], head[N], cnt, tag[N];
int treeDiameter, point, tagPoint;
struct Edge {
int nex, to;
}edge[N << 1];
inline void AddEdge (int u, int v) {
edge[++cnt].nex = head[u];
edge[cnt].to = v;
head[u] = cnt;
edge[++cnt].nex = head[v];
edge[cnt].to = u;
head[v] = cnt;
}
void dfs (int u, int fa, int len) {
if (len > treeDiameter) {
treeDiameter = len;
point = u;
}
for (int i = head[u]; i; i = edge[i].nex) {
int v = edge[i].to;
if (v != fa) {
dfs(v, u, len + 1);
}
}
}
bool dfs1 (int u, int fa, int len) {
if (len == treeDiameter) {
return false;
}
for (int i = head[u]; i; i = edge[i].nex) {
int v = edge[i].to;
if (v != fa) {
if (!dfs1(v, u, len + 1)) {
if (len == (treeDiameter >> 1)) {
tagPoint = u;
}
return false;
}
}
}
return true;
}
bool dfs2 (int u, int fa, int len) {
if (fa && deg[u] == 1) {
if (len == (treeDiameter >> 1)) return true;
else return false;
}
int cnt = 0;
for (int i = head[u]; i; i = edge[i].nex) {
int v = edge[i].to;
if (v != fa) {
if (!dfs2(v, u, len + 1)) return false;
cnt++;
}
}
if (cnt >= 3) return true;
else return false;
}
int main() {
#ifdef LOCAL
freopen("in.txt", "r", stdin);
// freopen("out.txt","w",stdout);
#endif
scanf("%d%d", &n, &k);
for (int i = 1; i <= n - 1; i++) {
int u, v;
scanf("%d%d", &u, &v);
deg[u]++;
deg[v]++;
AddEdge(u, v);
}
for (int i = 1; i <= n; i++) if (deg[i] == 1) {
tag[edge[head[i]].to]++;
}
for (int i = 1; i <= n; i++) if (tag[i] && tag[i] < 3) {
printf("No\n");
return 0;
}
dfs(1, 0, 0);
dfs(point, 0, 0);
if ((treeDiameter & 1) || k != (treeDiameter >> 1)) {
printf("No\n");
return 0;
}
dfs1(point, 0, 0);
// printf("%d %d %d\n", point, tagPoint, treeDiameter);
if (dfs2(tagPoint, 0, 0)) printf("Yes\n");
else printf("No\n");
return 0;
}
Codeforces - 1067C
神奇構造,參考題解:
代碼:
#include <bits/stdc++.h>
#define mst(a,b) memset(a,b,sizeof(a))
#define ALL(x) x.begin(),x.end()
#define pii pair<int,int>
#define eps 1e-6
#define debug(a) cout << #a": " << a << endl;
#define eularMod(a, b) a < b ? a : a % b + b
inline int lowbit(int x){ return x & -x; }
const int N = 1e5 + 10;
const int mod = (int) 998244353;
const int INF = 0x3f3f3f3f;
const long long LINF = (1LL << 62);
typedef long long LL;
typedef unsigned long long ULL;
const double PI = acos(-1.0);
using namespace std;
int main() {
#ifdef LOCAL
freopen("in.txt", "r", stdin);
// freopen("out.txt","w",stdout);
#endif
int n;
scanf("%d", &n);
for (int i = 0; ; i += 2) {
printf("%d %d\n", 0, i);
if (!(--n)) break;
printf("%d %d\n", 0, i + 1);
if (!(--n)) break;
printf("%d %d\n", 3, i + 1);
if (!(--n)) break;
}
return 0;
}