EPIC Institute of Technology Round August 2024 (Div. 1 + Div. 2) (A-D2)

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;
}

  • 10
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值