AGC006C & CF1110E

Posted skiceanakacniu

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了AGC006C & CF1110E相关的知识,希望对你有一定的参考价值。

这两个题都有一个公用的小trick,所以我就写一起了!

AGC 006 C

题目叙述

一些兔子站在坐标轴上,兔子的坐标为 (x_1,x_2,cdots ,x_n) 。第 (i) 只兔子会这样跳跃:随机等概率选择相邻两个兔子之一,以那只兔子为中心,跳到对称的另一边。现在定义一组跳跃为让编号为 (a_1,a_2,cdots ,a_n) 的这些兔子跳跃。求 (k) 次跳跃后每只兔子期望位置。

题解

首先有一个显而易见的 dp 。设 (f_i) 为第 (i) 只兔子目前位置的期望,每次按顺序执行跳跃,转移即可。复杂度 (mathcal O(mk))

然后在看到 (k le 10^{18}),可以想到矩阵乘法优化 dp。但复杂度为 (mathcal O(n^3log_2k))

考虑根据转移方程特点优化 dp 。发现每次 (f_i) 会变为 (f_{i-1}+f_{i+1}-f_i) 。这就相当于一个序列,每次选择一个位置 (i)(a_i) 变为 (a_{i-1}+a_{i+1}-a_i) 。考虑这样操作对差分数组的改变:

[egin{aligned} &a_1,a_2,a_3,a_4\Rightarrow&a_1,a_2-a_1,a_3-a_2,a_4-a_3&a_1,a_2,a_2+a_4-a_3,a_4\Rightarrow&a_1,a_2-a_1,a_4-a_3,a_3-a_2 end{aligned} ]

发现对 (i) 这个位置操作相当于交换 (i)(i+1) 的差分数组。

所以每一次操作相当于交换差分数组的两个位置。所以每一轮操作就是交换若干对数,不难发现这其实是若干个环的结构。也就类似于置换。那么每次求出一个数交换的环有多大,然后得到最终状态并通过差分数组还原原数组即可。

总结

  • dp 可以针对转移方程优化
  • (a_i ightarrow a_{i-1}+a_{i+1}-a_i) 这种可以考虑研究他的差分数组。

代码

#include <cstdio>
#include <vector>
using namespace std;
typedef long long ll;
const int N = 1e5 + 5;
int n, m, a[N], go[N], bg[N], ps[N];
ll k, chaf[N], ans[N], x[N];
bool vis[N];
vector<int> cir[N];
int main() {
	scanf("%d", &n);
	for (int i = 1; i <= n; ++i) scanf("%lld", &x[i]);
	for (int i = 1; i <= n; ++i) chaf[i] = x[i] - x[i - 1];
	scanf("%d%lld", &m, &k);
	for (int i = 1; i <= m; ++i) scanf("%d", &a[i]);
	for (int i = 1; i <= n; ++i) go[i] = i;
	for (int i = 1; i <= m; ++i) swap(go[a[i]], go[a[i] + 1]);
	for (int i = 1; i <= n; ++i) {
		if (vis[i]) continue ;
		int u = i;
		while (!vis[u]) {
			vis[u] = 1;
			bg[u] = i;
			u = go[u];
		}
		u = i;
		bg[u] = i;
		cir[i].push_back(u);
		ps[u] = 0;
		while (go[u] != i) {
			u = go[u];
			ps[u] = cir[i].size();
			cir[i].push_back(u);
		}
	}
	for (int i = 1; i <= n; ++i) ans[i] = chaf[cir[bg[i]][(ps[i] + k) % cir[bg[i]].size()]];
	for (int i = 1; i <= n; ++i) ans[i] += ans[i - 1];
	for (int i = 1; i <= n; ++i) printf("%lld
", ans[i]);
	return 0;
}

CF1110E

题目叙述

一个数组 (a) 考虑对他进行如下变换:

  • 每次可以选择位置 (i) 将第 (i) 个位置的数换为 (a_{i+1}+a_{i-1}-a_{i})

问是否能将 (a) 数组通过若干次变换变为 (t) 数组((a)(t) 都给定)。

题解

首先发现 (a_1)(a_n) 不可进行这种变换,所以 (a_1) 必然和 (t_1) 相等并且 (a_n)(t_n) 相等。

然后再看两个数组的差分数组是否可以通过交换若干次变为相同的。没了。

总结

没啥。被上一道题基本覆盖。。。

以上是关于AGC006C & CF1110E的主要内容,如果未能解决你的问题,请参考以下文章

AGC006C Rabbit Exercise

做题agc006C - Rabbit Exercise——模型转换

CF1110E Magic Stones

CF1110E Magic Stones - 差分

CF1110E Magic Stones

cf1110E 思维