首页 > 其他分享 >Good Bye 2022: 2023 is NEAR

Good Bye 2022: 2023 is NEAR

时间:2023-01-01 00:23:48浏览次数:58  
标签:Bye int LL long fa NEAR Good solve include

题目链接

A

核心思路:其实就是考察一个muliset的应用,这个和set的区别是它可以储存重复的元素。然后需要注意题目啊,必须得进行m次操作.

#include<iostream>
#include<set>
#include<cstring>
#include<algorithm>
#include<vector>
using namespace std;
typedef long long LL;
void solve()
{
	int n, m;
	cin >> n >> m;
	multiset<int> s;
	for (int i = 0;i < n;i++)
	{
		int x;
		cin >> x;
		s.insert(x);
	}
	while (m--)
	{
		int x;
		cin >> x;
		s.erase(s.begin());
		s.insert(x);
	}
	LL sum = 0;
	for (auto x : s)
		sum += x;
	cout << sum << endl;
}
int main()
{
	int T;
	cin >> T;
	while (T--)
	{
		solve();
	}
}

B

核心思路:这个一个最开始的思路是想先让最大值和最小值相隔k个单位,再让次大值和次小值相隔k个单位、、、、、。其实仔细一想根本没这个必要,我们只需要最大值和最小值交替安排就好了,这种情况肯定是符合的,因为随便你取一段连续的序列那个序列长度都是大于2的。

所以做构造题一定要多构造出几组数据。

#include<iostream>
#include<set>
#include<cstring>
#include<algorithm>
#include<vector>
using namespace std;
typedef long long LL;
const int N = 1e6 + 10;
int a[N];
void solve()
{
	int n, k;
	cin >> n >> k;
	for (int i = 1, j = n;i <= n;i += 2, j--)
		a[i] = j;
	for (int i = 2, j = 1;i <= n;i += 2, j++)
		a[i] = j;
	for (int i = 1;i <= n;i++)
		cout << a[i] << " ";
	cout << endl;
}
int main()
{
	int T;
	cin >> T;
	while (T--)
	{
		solve();
	}
}

C

核心思路:这个题目是有一定的深度的,首先简化问题:

\(gcd(a_i+x,a_i-a_j)=1\)也就是需要这两个数互质,但是我们可以发现\(t=a_i-a_j\)是一个常数,所以我们可以对t分解质因数,于是整个问题就变成了:\(a_i+x\neq0(\mod p)\),所以就需要x%p!=(p-a%p)%p;

所以我们可以令T=(p-a%p)%p,也就是x的解。我们可以统计使用map统计T的所有可能的解,如果个数是p就说明:

\(x\neq(0,1,....,p-1)\)在%p的前提下,这显然是不可能的。所以这就是无解的情况.

#include<iostream>
#include<set>
#include<cstring>
#include<map>
#include<algorithm>
#include<vector>
#include<bits/stdc++.h>
#include<random>
using namespace std;
typedef long long LL;
const int N = 1e3 + 10;
LL a[N];
int primes[N], st[N];
int cnt;
void Init()
{
	for (int i = 2;i <= N;i++)
	{
		if (!st[i])
			primes[cnt++] = i;
		for (int j = 0;i * primes[j] <= N;j++)
		{
			st[i * primes[j]] = 1;
			if (i % primes[j] == 0)
				break;
		}
	}
}
void solve()
{
	int n;
	cin >> n;
	map<LL, set<LL>> mp;
	for (int i = 1;i <= n;i++)
		cin >> a[i];
	int success = 1;
	for(int i=1;i<=n;i++)
		for (int j = i + 1;j <= n;j++)
		{
			if (a[i] == a[j])
			{
				success = 0;
			}
		}
	if (!success)
	{
		cout << "NO" << endl;
		return;
	}
	for (int i = 1;i <= n;i++)
	{
		set<LL> f;
		for (int j = 1;j <= n;j++)
		{
			if (i == j)
				continue;
			LL t = abs(a[i] - a[j]);
			for (int k = 0;k < cnt;k++)
			{
				int p = primes[k];
				if (t % p == 0)
					f.insert(p);
			}
		}
		for (auto x : f)
			mp[x].insert(((x - a[i] % x) % x));
	}
	for (auto p : mp)
	{
		if (p.first == p.second.size())
		{
			success = 0;
			break;
		}
	}
	cout << (success ? "YES" : "NO") << endl;
}
int main()
{
	Init();
	ios::sync_with_stdio(0);
	cin.tie(0), cout.tie(0);
	int T;
	cin >> T;
	while (T--)
	{
		solve();
	}
}

D

核心思路: 这题可以联想图论,虽然这个思路很难想。但是仔细一想好像也是那么回事。因为我们可以通过模拟有样例可以知道,对于\(a[i]和b[i]\),如果不相等的话我们必然可以构造出来\(c_i\)使得选中我们想要的那个数在\(a[i]和b[i]\)之间。

但是我们可以发现选出来的d数组必须还得是一个序列,所以我们就可以联想到\(a_i还与其他几个数存在联系\),所以这种联系我们可以使用图论表示。

其实我们可以挖掘出几个性质,通过对于\(a[i]和b[i]之间建立边之后\):

  1. 如果存在自环的话,那么答案需要乘上n.因为已经不管\(c_i\)什么事了,\(c_i可以随便选\)
  2. 一个连通块里面只有点数和边数是相等的,才有答案,并且答案需要乘上2.如果两个点之间有重复的边那必然不会相等,也就不会有解.

接下来我们可以使用并查集对这个数据结构进行维护.

#include<bits/stdc++.h>
using namespace std;
typedef long long LL;
const int N = 1e5 + 10;
const int mod = 998244353;
int fa[N], cnt_v[N], cnt_e[N], selfloop[N];
LL a[N], b[N], n;
int find(int x)
{
	if (x != fa[x])
		fa[x] = find(fa[x]);
	return fa[x];
}
void Init(int n)
{
	for (int i = 1;i <= n;i++)
	{
		fa[i] = i;
		cnt_v[i] = 1;
		cnt_e[i] = 0;
		selfloop[i] = 0;
	}
}
void merge(int u, int v)
{
	u = find(u);
	v = find(v);
	cnt_v[u] += cnt_v[v];
	cnt_e[u] += cnt_e[v];
	selfloop[u] |= selfloop[v];//因为如果某一个有了那么这个连通块肯定也有了
	fa[v] = u;
}
void solve()
{
	cin >> n;
	for (int i = 1;i <= n;i++)
		cin >> a[i];
	for (int i = 1;i <= n;i++)
		cin >> b[i];
	Init(n);
	for (int i = 1;i <= n;i++)
	{
		if (find(a[i]) != find(b[i]))
			merge(a[i], b[i]);
		cnt_e[find(a[i])]++;//自己千万不可以忘了.
		if (a[i] == b[i])
			selfloop[find(a[i])] = 1;
	}
	map<int, int> vis;
	LL ans = 1;
	for (int i = 1;i <= n;i++)
	{
		if (vis[find(i)])
			continue;
		if (cnt_e[find(i)] != cnt_v[find(i)])
			ans = 0;
		if (selfloop[find(i)])
			ans = (ans * n) % mod;
		else
			ans = (ans * 2) % mod;
		vis[find(i)] = 1;
	}
	cout << ans << endl;
}
int main()
{
    int T;
    cin>>T;
    while(T--)
    {
        solve();
    }
}

标签:Bye,int,LL,long,fa,NEAR,Good,solve,include
From: https://www.cnblogs.com/xyh-hnust666/p/17017639.html

相关文章

  • Goodbye 2022!!!!
    碌碌无为的一年。苍白的一年。没有什么令人欣喜的成果,也没有什么脚踏实地的进步。倒是目睹了勇士王朝再续辉煌,学长们纷纷成功,阿根廷又一位球王登基。也在混乱的疫情时代......
  • Goodbye 2022 Hello 2023!
    Goodbye2022今天在实验室群里偶然看见大家都在总结2022而我索性去翻了一下聊天记录整理出这样一篇总结说实话我臆想中的总结可能会在南京站知乎下发表那个世界里......
  • “Good-Exchanging” 软件开发经验浅谈
    需求分析本次开发将实现一个物资交换软件,具有以下基本功能:该程序允许添加物品的信息,删除物品的信息,显示物品列表,也允许查找物品的信息物品有公共的信息(物品名称,物品......
  • Good Bye 2022: 2023 is NEAR(持续更新)
    Preface2022的LastRound了,结果CD全卡住,反复横跳后最后才堪堪看出C的问题D的话其实我刚开始是准备写并查集的,但后来nt了不知道为什么想到边双去了写Tarjan去了唉只能说......
  • Good Bye 2022: 2023 is NEAR C
    GoodBye2022:2023isNEARC第一道题真是没理解,wa了好多次还好后来知道了题意就好做了,我现在在这里就补一下c,之前想了一会,还是不明白,后来想到了一些,容我讲一讲C这道......
  • Good Bye 2022: 2023 is NEAR
    A.KoxiaandWhiteboards(CF1770A)题目大意给定一个包含\(n\)个数的数组\(a\),以及\(m\)次操作。第\(i\)次操作将\(a\)中的一个数替换为\(b_i\)。问\(m\)次操......
  • Good Bye 2022: 2023 is NEAR D
    D.KoxiaandGametilian很容易发现就是我们要让每个数字都doublechoice一次才能得到答案比如第一个样例我们发现11已经doublechoice一次过了所以我们该点可以搞......
  • Good Bye 2022: 2023 is NEAR
    KoxiaandNumberTheory(鸽巢原理)题目大意给定一个长度为\(n(2\len\le100)\)的数组\((1\lea[i]\le10^{18})\),问是否存在一个正整数x,使得对于任意的i,j都满足\(gc......
  • Codeforces Good Bye 2022 CF 1770 A~E 题解
    题目链接A.KoxiaandWhiteboards注意每一步替换操作都是强制的,而不是可选的。所以就用一个multiset维护所有的数,每次选一个最小的替换掉即可。时间复杂度\(O(nlogn)\)......
  • Good Bye 2022: 2023 is NEAR
    D.KoxiaandGame记\(ans=\prod\limits_{i=1}^{i=n}add_i\),\(add_i\)就是\(i\)的贡献。记数字\(i\)只和自己连起来称为\(i\)自环。例如:123123则称\(1......