#include<iostream>
#include<cstdio>
#include<cstdlib>
#include<algorithm>
#include<cmath>
#include<queue>
using namespace std;
const int maxn = 1e6+7;
typedef long long ll;
ll n,m,pos[maxn],k,ans[maxn];
ll a[maxn],b[maxn],st[maxn];
ll move[maxn],vis[maxn];
int main()
{
scanf("%lld",&n);
for(int i=1;i<=n;i++)
scanf("%lld",&pos[i]); // 位置
for(int i=1;i<=n;i++)
b[i]=pos[i]-pos[i-1],a[i]=i; // 计算期望位置,运用差分进行巧妙转换 a[i]为位置
scanf("%lld%lld",&m,&k);
for(int i=1;i<=m;i++)
{
ll x;
scanf("%lld",&x);
swap(a[x],a[x+1]); // 变换位置
}
for(int t=1;t<=n;t++)
{
if(vis[t])continue; // 一个环上会全被处理掉,防止重复 保证复杂度
int round = 0;
for(int i=t;!vis[i];i=a[i])vis[i]=1,st[++round]=i; // 计算环,放到一个栈里
for(int i=1;i<=round;i++) ans[st[i]] = b[ st[(i+k-1)%round +1]]; // 类似取模的操作
} // i+k % round 求出了轮换后的位置,可以拿 ((k%round) + i)%round 理解
for(int i=1;i<=n;i++) // +1 -1 防止取模出 0
{
ans[i]+=ans[i-1]; // 看似每个兔子的期望值不再是连续的差分数列,实际上仍然满足前缀和
printf("%.1lf\n",(double)ans[i]);// 因为不管B的交换,它的性质还是当前减后面
}
return 0;
}
洛谷AT2164 rabbit exercise
最新推荐文章于 2022-01-30 19:38:32 发布