码迷,mamicode.com
首页 > 其他好文 > 详细

【AGC006C】Rabbit Exercise

时间:2021-02-01 11:47:44      阅读:0      评论:0      收藏:0      [点我收藏+]

标签:c++   def   计算   方便   lin   位置顺序   tco   printf   变化   

题目:

题目链接:https://atcoder.jp/contests/agc006/tasks/agc006_c
有 n 只兔子在一个数轴上,兔子为了方便起见从 1 到 n 标号,第 i 只兔子的初始坐标为 xi。兔子会以以下的方式在数轴上锻炼:一轮包含 m 个跳跃,第j个是兔子a[j] (2≤a[j]≤N?1,a是给出的长度为m的数组) 跳一下,这一下从 兔子a[j]? 1 和 兔子a[j] + 1 中等概率的选一个(假设选了 x),那么 a[j]号兔子 会跳到它当前坐标关于x的坐标的对称点。(注意,即使兔子的位置顺序变化了,但是编号仍保持不变,这里按兔子编号算)兔子会进行k轮跳跃,对每个兔子,请你求出它最后坐标的期望值。
\(n,m\leq 10^5,|x_i|\leq 10^9,k\leq 10^{18}\)

思路

首先考虑三只编号连续的兔子 \(a,b,c\),如果我们让 \(b\) 跳,那么不难计算出它期望会调到位置 \(a+c-b\)
也就是 \((a,b,c)\to (a,a+c-b,c)\)
我们把两个三元组都做一下差分,得到 \((a,b-a,c-b)\to (a,c-b,b-a)\)
发现在差分下其实就等价于交换两项。那么我们直接差分出来,然后倍增即可。
时间复杂度 \(O(n\log k+m)\)

代码

#include <bits/stdc++.h>
using namespace std;
typedef long long ll;

const int N=100010;
int n,m,nxt[N],id[N],b[N];
ll k,a[N];

int main()
{
	scanf("%d",&n);
	for (int i=1;i<=n;i++)
	{
		scanf("%lld",&a[i]);
		nxt[i]=id[i]=i;
	}
	for (int i=n;i>=1;i--)
		a[i]-=a[i-1];
	scanf("%d",&m); scanf("%lld",&k);
	for (int i=1,x;i<=m;i++)
	{
		scanf("%d",&x);
		swap(id[x],id[x+1]);
	}
	for (int i=1;i<=n;i++)
		nxt[id[i]]=i,id[i]=i;
	for (;k;k>>=1)
	{
		if (k&1)
		{
			for (int i=1;i<=n;i++) b[nxt[i]]=id[i];
			memcpy(id,b,sizeof(b));
		}
		for (int i=1;i<=n;i++) b[i]=nxt[nxt[i]];
		memcpy(nxt,b,sizeof(b));
	}
	for (int i=1;i<=n;i++)
	{
		a[id[i]]+=a[id[i-1]];
		printf("%lld.0\n",a[id[i]]);
	}
	return 0;
}

【AGC006C】Rabbit Exercise

标签:c++   def   计算   方便   lin   位置顺序   tco   printf   变化   

原文地址:https://www.cnblogs.com/stoorz/p/14349255.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!