Atcoder Grand 006 C-Rabbit Exercise

题意:

数轴上有n只兔子,第i只兔子的坐标为xi。

有一组操作,这组操作的第i个操作是要让第ai只兔子等概率的跳到自己关于第ai+1或第ai-1只兔子的对称点。

进行K组操作,求每只兔子最后坐标的期望值。

 

当第一只兔子$i$跳完,它的位置的期望是$x[i+1]+x[i-1]-x[i]$。

然后我们发现当有其他一只兔子$j$要以$i$为对称轴跳跃时$j$跳完坐标的期望就是以$i$的期望坐标为对称轴跳跃到的坐标。

所以每次相当于让$x[i]=x[i+1]+x[i-1]-x[i]$。

我们维护差分序列,每次相当于交换了相邻两个数。

先做完一组,得到了一个排列,之后连边找环,就能知道跳k组后的位置了。

#include<bits/stdc++.h>
#define N 100005
#define int long long
using namespace std;
int n,m,x[N],a[N],p[N],s[N],cnt;
long long k;
int be[N],num[N],v[N];
vector<int>q[N];
void dfs(int x,int dep)
{
    num[x]=dep;v[x]=1;be[x]=cnt;
    q[cnt].push_back(x);
    if(!v[p[x]])dfs(p[x],dep+1);
}
signed main()
{
    memset(v,0,sizeof(v));
    cin>>n;
    for(int i=1;i<=n;i++)cin>>x[i];
    for(int i=1;i<n;i++)s[i]=x[i+1]-x[i];
    cin>>m>>k;
    for(int i=1;i<n;i++)p[i]=i;
    for(int i=1;i<=m;i++){cin>>a[i];swap(p[a[i]],p[a[i]-1]);}
    for(int i=1;i<n;i++)if(!v[i])cnt++,dfs(i,0);
    cout<<x[1]<<endl;
    int now=x[1];
    for(int i=1;i<n;i++)
    {
        now+=s[q[be[i]][(num[i]+k)%q[be[i]].size()]];
        cout<<now<<endl;
    }
    return 0;
}

  

posted @ 2017-10-12 14:39  SD_le  阅读(423)  评论(0编辑  收藏  举报
重置按钮