A. Distanced Coloring
直接贪心
#include<bits/stdc++.h>
#define lowbit(x) (x&(-x))
#define rep(x,a,b) for(int x=a;x<=b;x++)
#define pre(x,a,b) for(int x=a;x>=b;x--)
#define ac puts("Yes")
#define wa puts("No")
#define int long long
#define endl "\n"
#define pb push_back
#define pii pair<int, int>
#define de cout<<1;
#define mem(a,x) memset(a,x,sizeof a)
#define IOS ios::sync_with_stdio(false); cin.tie(0); cout.tie(0);
#define ull unsigned long long
#define eps 1e-6
#define RI register int
#define CI const int&
using namespace std;
const int mod=998244353;
const int N = 1e6 + 20;
int n, m, k;
int a[N], b[N];
void solve()
{
int now = 1;
cin >> n >> m >> k;
int nd = min(m, k);
int ndd = min(k, n);
cout << nd * ndd << endl;
}
signed main()
{
IOS
int t;
t = 1;
cin >> t;
while(t -- )
{
solve();
}
return 0;
}
B. Removals Game
比较两个数组是否相等即可,正序判断一下然后倒序判断一下
#include<bits/stdc++.h>
#define lowbit(x) (x&(-x))
#define rep(x,a,b) for(int x=a;x<=b;x++)
#define pre(x,a,b) for(int x=a;x>=b;x--)
#define ac puts("Yes")
#define wa puts("No")
#define int long long
#define endl "\n"
#define pb push_back
#define pii pair<int, int>
#define de cout<<1;
#define mem(a,x) memset(a,x,sizeof a)
#define IOS ios::sync_with_stdio(false); cin.tie(0); cout.tie(0);
#define ull unsigned long long
#define eps 1e-6
#define RI register int
#define CI const int&
using namespace std;
const int mod=998244353;
const int N = 1e6 + 20;
int n, m, k;
int a[N], b[N];
void solve()
{
cin >> n;
rep(i, 1, n) cin >> a[i];
rep(i, 1, n) cin >> b[i];
int f1 = 0, f2 = 0;
rep(i, 1, n)
{
if(a[i] != b[i]) f1 = 1;
}
pre(i, n, 1)
{
if(a[i] != b[n - i + 1]) f2 = 1;
}
if(!f1 || !f2) cout << "Bob";
else cout << "Alice";
cout << endl;
}
signed main()
{
IOS
int t;
t = 1;
cin >> t;
while(t -- )
{
solve();
}
return 0;
}
C. Black Circles
追击问题,看各个圆到终点所需时间是否大于等于起点到终点的时间,注意不能用double有精度丢失,用longlong比较平方即可
#include<bits/stdc++.h>
#define lowbit(x) (x&(-x))
#define rep(x,a,b) for(int x=a;x<=b;x++)
#define pre(x,a,b) for(int x=a;x>=b;x--)
#define ac puts("Yes")
#define wa puts("No")
#define int long long
#define endl "\n"
#define pb push_back
#define pii pair<int, int>
#define de cout<<1;
#define mem(a,x) memset(a,x,sizeof a)
#define IOS ios::sync_with_stdio(false); cin.tie(0); cout.tie(0);
#define ull unsigned long long
#define eps 1e-6
#define RI register int
#define CI const int&
using namespace std;
const int mod=998244353;
const int N = 1e6 + 20;
int n, m;
double x[N], y[N];
double sx, sy, tx, ty;
int dis(int a, int b, int c, int d)
{
return (a - c) * (a - c) + (b - d) * (b - d);
}
void solve()
{
cin >> n;
rep(i, 1, n) cin >> x[i] >> y[i];
cin >> sx >> sy >> tx >> ty;
int len = dis(sx, sy, tx, ty);
rep(i, 1, n)
{
int l = dis(x[i], y[i], tx, ty);
if(l <= len)
{
cout << "NO" << endl;
return;
}
}
cout << "YES" << endl;
}
signed main()
{
IOS
int t;
t = 1;
cin >> t;
while(t -- )
{
solve();
}
return 0;
}
D1. DFS Checker (Easy Version)
完全二叉树,考虑每个深度的点在排列中的位置是固定的比如有7个点的完全二叉树,第三层的点在数组中的位置一定是3,4,6,7中的一个,因此预处理位置判断是否合法,然后判断每个点的父亲在数组中的位置一定在自己前面,每次交换x,y两个位置时判断一下x,y以及x,y的父亲以及x,y的儿子即可,每次最多维护8个点
#include<bits/stdc++.h>
#define lowbit(x) (x&(-x))
#define rep(x,a,b) for(int x=a;x<=b;x++)
#define pre(x,a,b) for(int x=a;x>=b;x--)
#define ac puts("Yes")
#define wa puts("No")
#define int long long
#define endl "\n"
#define pb push_back
#define pii pair<int, int>
#define de cout<<1;
#define mem(a,x) memset(a,x,sizeof a)
#define IOS ios::sync_with_stdio(false); cin.tie(0); cout.tie(0);
#define ull unsigned long long
#define eps 1e-6
#define RI register int
#define CI const int&
using namespace std;
const int mod=998244353;
const int N = 1e6 + 20;
int n, m;
vector<int>p[N];
int a[N], depth[N], f[N];
set<int>id[20];
void dfs(int u, int fa)
{
f[u] = fa;
depth[u] = depth[fa] + 1;
for(auto j : p[u])
{
if(j == fa) continue;
dfs(j, u);
}
}
void g(int l, int r, int cnt)
{
id[cnt].insert(l);
// cout<<cnt<<" "<<l<<endl;
if(l == r) return;
int len = r - l;
len /= 2;
g(l + 1, l + len, cnt + 1);
g(l + len + 1, r, cnt + 1);
}
set<int>mp;
int now[N];
bool check(int x)
{
if(id[depth[a[x]]].find(x) == id[depth[a[x]]].end()) return true;
if(f[a[x]] && now[f[a[x]]] > x) return true;
return false;
}
void solve()
{
mp.clear();
cin >> n >> m;
rep(i, 1, n) p[i].clear();
rep(i, 0, 19) id[i].clear();
rep(i, 2, n)
{
int x;
cin >> x;
p[i].push_back(x);
p[x].push_back(i);
}
rep(i, 1, n) cin >> a[i], now[a[i]] = i;
g(1, n, 1);
dfs(1, 0);
rep(i, 1, n)
{
if(check(i)) mp.insert(i);
}
// cout<<mp.size();
while(m -- )
{
int x, y;
cin >> x >> y;
swap(now[a[x]], now[a[y]]);
swap(a[x], a[y]);
if(check(x)) mp.insert(x);
else mp.erase(x);
if(check(y)) mp.insert(y);
else mp.erase(y);
if(f[a[x]] && check(now[f[a[x]]])) mp.insert(now[f[a[x]]]);
else mp.erase(now[f[a[x]]]);
if(f[a[y]] && check(now[f[a[y]]])) mp.insert(now[f[a[y]]]);
else mp.erase(now[f[a[y]]]);
for(auto j : p[a[x]])
{
if(j == f[a[x]]) continue;
if(check(now[j])) mp.insert(now[j]);
else mp.erase(now[j]);
}
for(auto j : p[a[y]])
{
if(j == f[a[y]]) continue;
if(check(now[j])) mp.insert(now[j]);
else mp.erase(now[j]);
}
if(mp.size() > 0) cout << "NO" << endl;
else cout << "YES" << endl;
}
}
signed main()
{
IOS
int t;
t = 1;
cin >> t;
while(t -- )
{
solve();
}
return 0;
}
D2. DFS Checker (Hard Version)
考虑数组中每个点它的前一个数一定是自己的父亲或者是父亲所在子树的某个叶子,且不能是自己所在子树的某个叶子,每次交换x,y发现只会影响x,x+1,y,y+1这四个点,可以先dfs把所有叶子处理成一段连续的数,然后维护每个点的叶子所属的区间判断一下即可。
#include<bits/stdc++.h>
#define lowbit(x) (x&(-x))
#define rep(x,a,b) for(int x=a;x<=b;x++)
#define pre(x,a,b) for(int x=a;x>=b;x--)
#define ac puts("Yes")
#define wa puts("No")
#define int long long
#define endl "\n"
#define pb push_back
#define pii pair<int, int>
#define de cout<<1;
#define mem(a,x) memset(a,x,sizeof a)
#define IOS ios::sync_with_stdio(false); cin.tie(0); cout.tie(0);
#define ull unsigned long long
#define eps 1e-6
#define RI register int
#define CI const int&
using namespace std;
const int mod=998244353;
const int N = 1e6 + 20;
int n, m;
vector<int>p[N];
int dd = 0;
int l[N], r[N], idx;
int a[N], depth[N], f[N], now[N];
void dfs(int u, int fa)
{
f[u] = fa;
l[u] = 1e9;
r[u] = 0;
int f = 0;
for(auto j : p[u])
{
if(j == fa) continue;
dfs(j, u);
f = 1;
l[u] = min(l[u], l[j]);
r[u] = max(r[u], r[j]);
}
if(!f) l[u] = r[u] = ++idx;
}
bool check(int x)
{
if(x == 1 && a[x] != 1) return true;
else if(x == 1) return false;
if(a[x - 1] == f[a[x]]) return false;
int tl = l[f[a[x]]], tr = r[f[a[x]]];
if(p[a[x - 1]].size() != 1) return true;
int id = l[a[x - 1]];
if(id >= tl && id <= tr && (id < l[a[x]] || id > r[a[x]])) return false;
return true;
}
void solve()
{
dd = 0;
idx = 0;
cin >> n >> m;
rep(i, 1, n) p[i].clear();
rep(i, 2, n)
{
int x;
cin >> x;
p[i].push_back(x);
p[x].push_back(i);
}
rep(i, 1, n) cin >> a[i], now[a[i]] = i;
dfs(1, 0);
set<int>s;
rep(i, 1, n)
{
if(check(i))
{
s.insert(i);
// cout<<i<<endl;
}
}
while(m -- )
{
int x, y;
cin >> x >> y;
swap(a[x], a[y]);
swap(now[a[x]], now[a[y]]);
if(check(x)) s.insert(x);
else s.erase(x);
if(check(y)) s.insert(y);
else s.erase(y);
if(x + 1 <= n && check(x + 1)) s.insert(x + 1);
else s.erase(x + 1);
if(y + 1 <= n && check(y + 1)) s.insert(y + 1);
else s.erase(y + 1);
if(s.size() > 0) cout << "NO" << endl;
else cout << "YES" << endl;
}
}
signed main()
{
IOS
int t;
t = 1;
cin >> t;
while(t -- )
{
solve();
}
return 0;
}