StkOvflow

STACK OVERFLOW!

一言(ヒトコト)

想和zn谈恋爱
——lmh

CF思维体操

Plus and Multiply

Luogu
CF

题意简述:

给定 n, a, b,要求判断 n 能不能由 a 通过若干次 ×a 或者 +b得到。

解题思路:

我们首先应该找到能由上述操作得到的数的普遍形式。

n=ax+by(x,yN)n

我们可以证明一下这个形式可行,对于第一个数 1,显然可以表示成 a0+0·b,所以对于 1 是成立的。如果 ax+by 是成立的,那么进行 ×a 操作后变为 ax+1+by,进行 +b 操作后变为 ax+b(y+1),形式仍然不变,所以我们这个形式是具有普遍可行性的。

n=ax+bynax=bynax0 (mod b)

因此我们只需要依次枚举 x,并且判定即可,另外要注意的是 a=1 要特判,否则 TLE

#include <bits/stdc++.h>
#define pb emplace_back

using namespace std;
using PII = pair<int, int>;

int main() {
	int tc;
	scanf("%d", &tc);
	while (tc -- ) {
		int n, a, b;
		scanf("%d%d%d", &n, &a, &b);
		if (a == 1) 
			puts((n - 1) % b == 0 ? "Yes" : "No");
		else {
			int flag = 0;
			for (long long i = 1; !flag && i <= n; i *= a) 
				if ((n - i) % b == 0) flag = 1;
			puts(flag ? "Yes" : "No");
		}
	}
	return 0;
}

Ehab the Xorcist

Luogu
CF

题意简述

给定两个数 u, v,要求构造一个数列使得数列的异或和为 u, 数列的数值和为 v

解题思路

定义 Δ=vu从异或的角度出发,因为异或是二进制下的不进位加法,所以异或和一定不能大于数值和。所以当 Δ<0的时候,无解。另外这里有一个很重要的性质,即数列的异或和与数值和的奇偶性相同。证明如下:

axorb+2(a&b)=a+ba+baxorb=2(a&b)

因为 2(a&b) 是偶数,所以两个数的异或和与数值和奇偶性相同,以此类推即可.
所以我们可以对 Δ 进行一下分类讨论:

1.Δ<0,

2.Δ=0,u=0,{0}{u}

3.Δ>0Δ

4.Δ>0Δxoru=u{Δ,u}

5.Δ>0Δxoruu

5 种情况需要一定的思考,因为 Δ 一定是偶数,两个相同的数异或和为 0, 一个数与 0 异或得本身,那不妨把 Δ 拆成两块,每块为 x,目标数列为{x,x,u}

#include <bits/stdc++.h>
#define pb emplace_back

using namespace std;
using PII = pair<int, int>;
using LL = long long;

int main() {
	LL u, v;
	scanf("%lld%lld", &u, &v);
	LL delta = v - u;
	if (delta & 1 || delta < 0) puts("-1");
	else {
		if (delta == 0) {
			if (u == 0) puts("0");
			else printf("1\n%lld\n", u);
		}
		else {
			LL x = delta >> 1;
			if ((u ^ delta) != u) {
				if ((x ^ (x + u)) != u) {
					puts("3");
					printf("%lld %lld %lld\n", x, x, u);
				} else {
					puts("2");
					printf("%lld %lld\n", x + u, x);
				}
			} else {
				puts("2");
				printf("%lld %lld\n", delta, u);
			}
		}
	}
	return 0;
}

Orac and Medians

Luogu
CF

题意简述

给定一个序列,每次可以将一段区间修改为区间中位数,问能否将整个序列全部改为 k

解题思路

我们可以先看看我们的操作有什么性质:

1.

2.

由这两条性质可以推出以下几条:

1.k,k

2.kkk

3.>=k,>=kkk

以上条件只要满足任意一个,就可以成功,否则不行。
逐个判定就行了。

#include <bits/stdc++.h>
#define pb emplace_back

using namespace std;
using PII = pair<int, int>;
using LL = long long;

int a[100010];

int main() {
	int tc;
	scanf("%d", &tc);
	while (tc -- ) {
		int n, k;
		scanf("%d%d", &n, &k);
		for (int i = 1; i <= n; i ++ ) scanf("%d", &a[i]);
		if (n == 1 && a[n] != k) puts("no");
		else {
			if (n == 1) puts("yes");
			else {
				int flag = 0, has = 0;
				for (int i = 1; i <= n; i ++ )
					has |= a[i] == k;
				if (!has) puts("no");
				else {
					for (int i = 1; i < n && !flag; i ++ ) 
						flag |= (a[i] >= k && a[i + 1] >= k);
					if (flag) puts("yes");
					else {
						for (int i = 1; i < n - 1 && !flag; i ++ )
							flag |= (a[i] >= k && a[i + 2] >= k);
						if (flag) puts("yes");
						else puts("no");
					}
				}
				
			}
		}
	}
	return 0;
}
posted @   StkOvflow  阅读(17)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 分享4款.NET开源、免费、实用的商城系统
· 全程不用写代码,我用AI程序员写了一个飞机大战
· MongoDB 8.0这个新功能碉堡了,比商业数据库还牛
· 白话解读 Dapr 1.15:你的「微服务管家」又秀新绝活了
· 上周热点回顾(2.24-3.2)
点击右上角即可分享
微信分享提示