AtCoder Beginner Contest 050

Addition and Subtraction Easy

读入两个数,输出两个数。

#include<bits/stdc++.h>
using namespace std;
const int N = 1e5 + 100;
int n, m;
char c;
int main() {
	ios::sync_with_stdio(false);
	cin.tie(0), cout.tie(0);
	cin >> n >> c >> m;
	if (c == '+') cout << n + m;
	else cout << n - m;
	return 0;
}

Contest with Drinks Easy

首先 \(O(n)\) 求出总时间,然后对于每一个饮料,用现在的减去之前的就行了。

时间复杂度 \(O(n)\)

#include<bits/stdc++.h>
#define int long long
using namespace std;
const int N = 1e5 + 100;
int n, m, num[N], sum;
signed main() {
	ios::sync_with_stdio(false);
	cin.tie(0), cout.tie(0);
	cin >> n;
	for (int i = 1; i <= n; i++) cin >> num[i], sum += num[i];
	cin >> m;
	for (int i = 1; i <= m; i++) {
		int id, x;
		cin >> id >> x;
		cout << sum + x - num[id] << '\n';
	}
	return 0;
}

Lining Up

考虑如果第 \(x\) 个人,现在右移一个,那么差值变化了 \(2\),按照这个性质先处理合法性。

注意分辨奇偶。

然后差值相同的两个人位置可以互换,答案为 \(2^{\frac{n}{2}}\)

#include<bits/stdc++.h>
#define int long long
using namespace std;
const int N = 1e5 + 100, MOD = 1e9 + 7;
int n, m, buc[N], x, cnt, tmp;
int qpow(int a, int b) {
	int ans = 1;
	while (b) {
		if (b & 1) ans = ans * a % MOD;
		a = a * a % MOD;
		b >>= 1;
	}
	return ans;
}
signed main() {
	ios::sync_with_stdio(false);
	cin.tie(0), cout.tie(0);
	cin >> n;
	for (int i = 1; i <= n; i++) cin >> x, buc[x]++;
	for (int i = !(n & 1); i <= n - 1; i += 2) {
		if (buc[i] != 2 && i) {
			cout << 0;
			return 0;
		}
		if (!i && buc[i] > 1) {
			cout << 0;
			return 0;
		}
		tmp += buc[i];
		if (i) cnt++;
	}
	if (tmp != n) {
		cout << 0;
		return 0;
	}
	cout << qpow(2, cnt);
	return 0;
}

Xor Sum

这是这场比赛最有价值的题目,就是冲着这个来的。

一个很明显的事实是 \(n\) 特别大,不难想到按照数位统计答案。

同时有 \(a+b \ge a \oplus b\)

然后我就卡住了。。。

因为上面那个等式,我们可以用 \(a+b\) 为状态进行转移,设 \(dp_{i,j}\) 表示考虑了 \(i\) 位(注意从高位开始考虑),当前考虑过的和为 \(j\)

当前这一位有三种情况:\((0,0),(0,1),(1,1)\)

对于总和的贡献,设之前的总和 \(sum^\prime\)

\[sum = \begin{cases} 2\times sum^\prime \\ 2\times sum^\prime + 1 \\ 2\times sum^\prime + 2 \end{cases} \]

有转移式:\(dp_{i,j} = dp_{i,\frac{j}{2}}+dp_{i,\frac{j-1}{2}}+dp_{i,\frac{j-2}{2}}\)

很显然每转移一次 \(j\) 变为原来一半,三个 \(DP\) 转移必有两个相等,同时有形如 \({\Large\lfloor}\cfrac{\cfrac{x-1}{2}}{2}{\Large\rfloor} = {\Large\lfloor}\cfrac{\cfrac{x}{2}-1}{2}{\Large\rfloor}\),记忆化搜索后状态数量 \(O(\log n)\)

#include<bits/stdc++.h>
#define int long long
using namespace std;
const int N = 1e5 + 100, MOD = 1e9 + 7;
int n, m, dp[N];
int Hash(pair<int, int> p) {
	int tmp = p.first << 13;
	tmp -= 500;
	tmp += p.second;
	tmp <<= 2;
	return tmp;
}
unordered_map<int, int> mp;
int Memdp(int x, int y) {
	if (mp.count(Hash({ x,y }))) return mp[Hash({ x, y })];
	if (!x) return mp[Hash({ x,y })] = min(2ll, y) + 1;
	int ans = Memdp(x - 1, y >> 1);
	if (y >= 1) ans = (ans + Memdp(x - 1, (y - 1) >> 1)) % MOD;
	if (y >= 2) ans = (ans + Memdp(x - 1, (y - 2) >> 1)) % MOD;
	return mp[Hash({ x,y })] = ans;
}
signed main() {
	ios::sync_with_stdio(false);
	cin.tie(0), cout.tie(0);
	cin >> n;
	cout << Memdp(60, n);
	return 0;
}

posted @ 2025-09-27 17:05  OrangeRED  阅读(10)  评论(0)    收藏  举报