首页 > 其他分享 >板刷 AGC

板刷 AGC

时间:2023-11-20 18:34:03浏览次数:41  
标签:cnt 板刷 AGC len mu int ff include

从 AGC001A 开始。

[AGC001A] BBQ Easy

显然排序后所有奇数位相加即为答案。

#include <iostream>
#include <cstdio>
#include <algorithm>
#include <cmath>
#include <cstring>
#include <vector>
using namespace std;

const int N = 205;
int n, a[N];

int main()
{
	ios::sync_with_stdio(0), cin.tie(0);
	cin >> n;
	n *= 2;
	for (int i = 1; i <= n; i++) cin >> a[i];
	int ans = 0;
	sort(a + 1, a + n + 1);
	for (int i = 1; i <= n; i += 2) ans += a[i];
	cout << ans << "\n";
	return 0;
}

[AGC001C] Shorten Diameter

考虑贪心。

每次找出直径,显然我们能删的只有直径端点。一棵树的直径端点必然是叶子,否则就不是最长链了。

考虑有两个端点,删哪个更优。比较显然的是删掉在树中能到距离 $>k$ 的点较多的那个。

#include <iostream>
#include <cstdio>
#include <algorithm>
#include <cmath>
#include <cstring>
#include <vector>
#include <queue>
using namespace std;

const int N = 2005;

int n, k;
vector<int> G[N];

int mxlen, mu;
int ff[N];

void dfs(int u, int fa, int len)
{
	ff[u] = fa;
	if (len > mxlen)
	{
		mxlen = len;
		mu = u;
	}
	for (auto& j : G[u])
	{
		if (j ^ fa) dfs(j, u, len + 1);
	}
}

int cnt = 0;

void get_cnt(int u, int f, int len)
{
	if (len > k) cnt++;
	for (auto& j : G[u])
	{
		if (j != f) get_cnt(j, u, len + 1);
	}
}

int solve()
{
	mxlen = -1, mu = 0;
	dfs(1, 0, 0);
	int u = mu;
	mu = 0, mxlen = -1;
	dfs(u, 0, 0);
	int res = mxlen;
	cnt = 0;
	get_cnt(u, 0, 0);
	int c1 = cnt;
	cnt = 0;
	get_cnt(mu, 0, 0);
	int c2 = cnt;
	if (c2 > c1)
	{
		if (ff[mu]) G[ff[mu]].erase(find(G[ff[mu]].begin(), G[ff[mu]].end(), mu));
	}
	else
	{
		dfs(mu, 0, 0);
		mu = u;
		if (ff[mu]) G[ff[mu]].erase(find(G[ff[mu]].begin(), G[ff[mu]].end(), mu));
	}
	return res;
}

int main()
{
	ios::sync_with_stdio(0), cin.tie(0);
	cin >> n >> k;
	for (int i = 1; i < n; i++)
	{
		int u, v;
		cin >> u >> v;
		G[u].emplace_back(v);
		G[v].emplace_back(u);
	}
	int ans = 0;
	while (solve() > k) ans++;
	cout << ans << "\n";
	return 0;
}

[AGC001D] Arrays and Palindrome

考虑回文的本质是什么。即第一个和最后一个相等,第二个和倒数第二个相等,……。

先考虑如果给定 $a$ 和 $b$ 怎么判定。我们考虑图论建模,对于每个 $a_i$ 和 $b_i$ 在对应范围内两两头尾相连。容易知道总共连了 $\sum \limits_{i=1}^n \lfloor \dfrac{a_i}{2} \rfloor + \sum \limits_{i=1}^n \lfloor \dfrac{b_i}{2} \rfloor$ 条边。如果最终图连通,则必然符合题意。

图连通的必要条件是边数 $\geq n-1$,又发现无论如何构造 $b$,$b$ 队边的贡献不超过 $\lfloor \dfrac{n}{2} \rfloor$,从而推出 $a$ 中奇数个数不超过 $2$。否则 impossible

把 $a$ 中两个奇数放两边,如果只有一个奇数就放在 $1$ 的位置。其他在中间随便排,最终让 $b_1 = a_1+1$,$b_i = a_i(2 \leq i < m)$,$b_m=a_m-1$,手玩一下发现很对。

#include <iostream>
#include <algorithm>
#include <cmath>
#include <cstring>
#include <string>
#include <vector>
using namespace std;

const int N = 1e5 + 5;

int n, m, a[N];
vector<int> ans;

void solve_1()
{
	for (int i = 1; i <= n / 2; i++) ans.emplace_back(2);
	ans.emplace_back(1);
}

void solve_2()
{
	for (int i = 1; i < n / 2; i += 2)
	{
		ans.emplace_back(2);
	}
	ans.emplace_back(1);
	for (int i = n / 2 + 2; i < n; i += 2) ans.emplace_back(2);
	ans.emplace_back(1);
}

bool vis[N];
int na[N];

int main()
{
	ios::sync_with_stdio(0), cin.tie(0);
	cin >> n >> m;
	for (int i = 1; i <= m; i++)
	{
		cin >> a[i];
	}
	if (m == 1)
	{
		if (n & 1) solve_1();
		else solve_2();
		cout << a[1] << "\n";
		cout << ans.size() << "\n";
		for (auto& i : ans) cout << i << " ";
		return 0;
	}
	int sum = 0;
	for (int i = 1; i <= m; i++)
	{
		sum += (a[i] >> 1);
	}
	if (sum + (n / 2) < n - 1)
	{
		cout << "Impossible\n";
		return 0;
	}
	bool f = 0;
	int c = 0;
	for (int i = 1; i <= m; i++)
	{
		if (a[i] & 1)
		{
			c++;
			vis[i] = 1;
			if (!f)
			{
				na[1] = a[i];
				f = 1;
			}
			else na[m] = a[i];
		}
	}
	int idx = (f ? 2 : 1);
	for (int i = 1; i <= m; i++)
	{
		if (!(a[i] & 1))
		{
			na[idx++] = a[i];
		}
	}
	ans.emplace_back(na[1] + 1);
	for (int i = 2; i < m; i++) ans.emplace_back(na[i]);
	if (na[m] != 1) ans.emplace_back(na[m] - 1);
	for (int i = 1; i <= m; i++) cout << na[i] << " ";
	cout << "\n";
	cout << ans.size() << "\n";
	for (auto& i : ans) cout << i << " ";
	cout << "\n";
	return 0;
}

标签:cnt,板刷,AGC,len,mu,int,ff,include
From: https://www.cnblogs.com/happybob/p/17844559.html

相关文章

  • 鸿蒙原生应用/元服务开发-AGC分发如何编译打包应用
    软件包规范在正式打包应用前,请确保已了解HarmonyOS应用软件包规范。操作步骤1.打开DevEcoStudio,菜单选择“Build>BuildHap(s)/APP(s)>BuildAPP(s)”。2.等待编译构建。编译完成后,将在工程目录“build>outputs>default”目录下,获取可用于发布的应用包。APIVersion4至7......
  • AGC041D-Problem Scores 题解
    题目链接luoguatcoder分析令\(k=\left\lfloor\frac{n}{2}\right\rfloor\)对于第三个条件,只需要满足\(\sum_{i=1}^{k+1}a[i]<\sum_{i=n-k+1}^{n}a[i]\)即可有一个\(trick\):构造一个单调不降或不增的序列可以转化为每次做一次前缀加操作例如本题要求构造一个单调......
  • AT AGC043C - Giant Graph - 总结
    ATAGC043C-GiantGraph因为\({(10^{18})}^{x+y+z}\)的底数很大,所以我们贪心的选择\(x+y+z\)大的点是存在正确性的。那么我们从小点向大点连有向边,形成DAG后,对于一个点,如果它指向的点都没有被选取,那么选择它,否则不选。我们发现这样的选取过程和求SG函数是一样的,并且每......
  • AT_agc057_e 题解
    AT_agc057_e[0]约定\(r_i=\sum\limits_{j=1}^{m}[A_{i,j}\lek]\)\(r^{'}_i=\sum\limits_{j=1}^{m}[B_{i,j}\lek]\)\(c_j=\sum\limits_{i=1}^{n}[A_{i,j}\lek]\)\(c^{'}_j=\sum\limits_{i=1}^{n}[B_{i,j}\lek]\)[1]......
  • AGC034E
    虽然做法大致相同,但是本篇题解将会讲述如何想出正解,分享我的思路。望通过。首先看到题目,容易想到一个简单很多的情况:在一条链上,且终点确定。此时就可以把终点两边的点分开,分别计算到终点的距离之和,看是否相等即可。没有确定终点时,枚举一个终点即可。考虑将这种做法带入本题。先......
  • AGC014E
    居然自己想出了AGCE。首先考虑删边再加红边的本质是什么。容易发现,如果一条目标树上的边当前还没有被加上,且这条边所连两点在原树上的路径被切断,则此时一定无解。因为不管怎么加删边,这都是一棵树,而此时两点路径上一定有红边。所以,我们就可以得到此时可以新增一条边\((u,v)\)......
  • AGC046C
    这是一种dp状态不那么抽象的组合数做法。但是很复杂,仅供参考。经过思考后发现,我们可以将字符串串按零的位置割开并分成若干个子串,设\(a_i\)表示第\(i\)个子串中\(1\)的个数(子串长度),这样就能转化为每一次操作将后面的一个数减\(1\),前面的一个数加\(1\),求操作数小于等于......
  • [AGC061A] Long Shuffle 题解
    题意给定一个满足\(A_i=i\)的排列\(A\),求对其进行一次\(\mathrm{shuffle}(1,N)\)操作后其第\(K\)项的值。其中\(\mathrm{shuffle}(L,R)\)的定义如下:若\(R=L+1\),那么交换\(A_L\)和\(A_R\)的值否则,依次执行\(\mathrm{shuffle}(L,R-1)\),\(\mathrm{shuffle}(......
  • ARC板刷计划
    板刷自ARC104起所有ARC的\(\text{C}\sim\text{E}\)题。进度:https://kenkoooo.com/atcoder/#/table/lsj2009。ARC104https://atcoder.jp/contests/arc104/tasks/arc104_c。ARC104C首先观察性质。容易发现的是,如果两个人在电梯上的时间段有交,必然只会是如下可能:也就......
  • AGC304Ex Constrained Topological Sort 题解
    AT一个直接的想法是拓扑排序时从小到大标号:每次在入度为\(0\)的点中找到\(l_{u}\lei\)且\(r_{u}\)最小的\(u\),令\(p_{u}=i\)问题是如果\(r_{u}\)很大,那么\(u\)被标号的优先级很低,会连累\(u\)的后继中\(r\)较小的点做法是倒着拓扑一遍,令\(r_{u}\leftarrow\m......