CF构造场+掉分场2071

省流:通过 A,B,D,C 拼尽全力无法做出。rk2292,+26 变为 1554 specialist(实际上我应该在这场比赛就已经 >=1600 expert 了,因为每次 div.2 我都能涨 100+pts)。

默哀 Timmyliuyunxi 以 candidate master 的理论极强实力打出了 rk2031 的成绩。-79,1994->1915 有些危险。

C 题果然是妙妙题,还得多练。

B 题卡思路卡的太久了。D 题调的太久了。

本场最重要的能力:注意力。

A.The Play Never Ends

https://codeforces.com/contest/2071/problem/A

赛时靠观察样例,注意到输出 YES 当且仅当 k ≡ 1 (   m o d   3 ) k \equiv 1(\bmod 3) k1(mod3)。一交过了。

请叫我猜结论大师\kx


给出严谨性证明(感性?):

易得,一旦第一场比赛胜负已定,接下来的比赛就完全可以预料了。(可以自由的规定谁输谁赢)

于是不妨假设如果 Sosai \text {Sosai} Sosai 赢得了 Fofo \text {Fofo} Fofo 观战的第一场比赛。

无论谁在第二场比赛中获胜, Hohai \text {Hohai} Hohai 都无法继续参加第三场比赛(即使他在第二场比赛中获胜),因为他已经连续参加了两场比赛。

同样, Fofo \text {Fofo} Fofo 也无法参加第四场比赛,因为无论比赛结果如何,他都已经连续参加了两场比赛。

因此,对于任何形如 3 x + 1 3x+1 3x+1 k k k, 福福都不能在第 k k k 场比赛中旁观。

证毕。

B.Perfecto

https://codeforces.com/contest/2071/problem/A

构造题我还是太菜了。

写一下心路历程:

  • 构造题传统的面向数据,先观察样例。

  • 发现 n = 1 n=1 n=1 时是 -1,哦哦哦,所有数的总和不能是完全平方数。

  • 发现 n = 4 n=4 n=4 是若干递增的偶数排上若干递增的奇数,考虑这样构造。然后发现 n = 5 n=5 n=5 时是对的!

  • 信心满满的提交,Wrong answer on pretest 2。

  • 炸了,B 都不能一遍过。发现 n = 6 n=6 n=6 时这种方法坠机,考虑其他方法。

  • 试着打了一下 n = 6 n=6 n=6 的表,发现情况数挺多。排列?我想到了什么?随机化?

  • 于是使用 random_shuffle() 对排列进行打乱,每次判断一下是否满足条件即可。优化了一下常数,发现第一位一定可以是 2 2 2

  • 一交,过了。之后就再也没有被 hack 过。

发现石老师的方法明显简洁一些啊!不过代码略微长了一点。拜谢 Master 巨佬。

#include <bits/stdc++.h>
#define int long long
using namespace std;
int t;
const int N = 500010;
int a[N];

signed main() {
	cin >> t;
	while (t--) {
		int n;
		cin >> n;
		int x = n * (n + 1) / 2;
		int y = sqrt(x);
		if (y * y == x) {//先判断
			cout << "-1\n";
			continue;
		}
		for (int i = 1; i <= n; i++)
			a[i] = i;
		a[1] = 2, a[2] = 1;//常数优化
		while (1) {
			bool f = 1;
			random_shuffle(a + 2, a + n + 1);//随机化
			int cnt = 0;
			for (int i = 1; i <= n; i++) {
				cnt += a[i];
				int y = sqrt(cnt);
				if (y * y == cnt) {
					f = 0;
					break;
				}
			}
			if (f == 1) {
				for (int i = 1; i <= n; i++)
					cout << a[i] << " ";
				cout << endl;
				break;//找到就退出
			}
		}
	}
	return 0;
}

C.Trapmigiano Reggiano

比赛结束前一分钟写完,交上去不过,狂怒。

才发现自己的方法不是正解,笑抽了。

原因:以 s t st st 为树根,和正解的以 e n en en 为树根恰好相反。


妙妙题。

一点也不易得 s t st st 为树根时这个问题有点难解,考虑以 e n en en 为根。

插叙:前三题不涉及很高级的算法,需要的是数学能力。想到 s t st st e n en en 的路径长度时竟然没有想到将 e n en en 作为树根,可太强了/cf。

注意到当从深度最高的结点一直循环到深度低的结点时, s t st st 的位置一定是 e n en en

然后就发现没有可能是 − 1 -1 1,纯纯诈骗。

于是这道题就做完了。

#include <bits/stdc++.h>
using namespace std;
int t;
int n, st, en;
const int N = 100010;
int dep[N];
vector<int> v[N], p[N];//v表示邻接表,p表示每一个深度对应的点编号

void dfs(int u, int pre) {
	dep[u] = dep[pre] + 1;
	p[dep[u]].push_back(u);//记录
	for (auto i : v[u])
		if (i != pre)
			dfs(i, u);
}

int main() {
	cin >> t;
	while (t--) {
		cin >> n >> st >> en;
		for (int i = 1; i <= n; i++)
			v[i].clear(), dep[i] = 0, p[i].clear();
		for (int i = 1; i < n; i++) {
			int x, y;
			cin >> x >> y;
			v[x].push_back(y);
			v[y].push_back(x);
		}
		dfs(en, 0);//核心
		for (int i = n; i >= 1; i--)
			for (auto j : p[i])
				cout << j << " ";//从深度大的点进行遍历
		cout << endl;
	}
	return 0;
}

D1.Infinite Sequence (Easy Version)

https://codeforces.com/contest/2071/problem/D1

递归+分类讨论。

发现当 m > n m>n m>n,且 m m m 为偶数时, a m a_m am a m + 1 a_{m+1} am+1 会相同,也就是 xor 起来会抵消掉,变成 0 0 0

于是只需要分类讨论一下 x x x n n n 的奇偶性即可。

#include <bits/stdc++.h>
#define int long long
using namespace std;
int t;
const int N = 200010;
int a[N];
int n, l, r;
int sum[N];//异或前缀和

int get(int x) {//求a_1 xor a_2 xor a_x
	if (x <= n)
		return sum[x];
	if (x % 2 == 1) {
		if (n % 2 == 1)
			return sum[n];//全部抵消掉了
		else
			return sum[n] ^ get((n + 1) / 2);
	} else {
		if (n % 2 == 1)
			return sum[n] ^ get(x / 2);
		else
			return sum[n] ^ get(x / 2)^get((n + 1) / 2);
	}
}

int get_ans(int x) {//计算 a_x
	if (x <= n)
		return a[x];
	else
		return get(x / 2);
}

signed main() {
	cin >> t;
	while (t--) {
		cin >> n >> l >> r;
		for (int i = 1; i <= n; i++)
			cin >> a[i], sum[i] = sum[i - 1] ^ a[i];
		cout << get_ans(l) << endl;
	}
	return 0;
}

因为浪费时间过多,错过场切 D2(提高+/省选-),可耻!!!

D2 使用 data structures 维护即可。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值