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

[Atcoder Grand 006 C] Rabbit Exercise 解题报告 (期望DP)

时间:2018-07-20 21:11:32      阅读:228      评论:0      收藏:0      [点我收藏+]

标签:ble   sid   input   格式   size   coder   after   psu   init   

题目链接:https://www.luogu.org/recordnew/show/8712459

     https://agc006.contest.atcoder.jp/tasks/agc006_c

题目描述

NN 匹のうさぎがいます。 うさぎ達は 11 から NN まで番号が振られています。 最初、うさぎ ii は数直線上の座標 x_ixi? にいます。

うさぎ達は体操をすることにしました。 11 セット分の体操は、次のような合計 MM 回のジャンプからなります。 jj 回目のジャンプでは、うさぎ a_jaj? ( 2\ \leq\ a_j\ \leq\ N-12  aj?  N1 ) がジャンプします。 このとき、うさぎ a_j-1aj?1 かうさぎ a_j+1aj?+1 のどちらかが等確率で選ばれ(これをうさぎ xx とします)、うさぎ a_jaj? はうさぎ xx に関して対称な座標へジャンプします。

以上の合計 MM 回のジャンプを 11 セット分の体操として、うさぎ達は KK セット分の体操を続けて繰り返します。 各うさぎについて、最終的な座標の期待値を求めてください。

输入格式:

The input is given from Standard Input in the following format:

  $ N $  
  $ x_1 $     $ x_2 $     $ ... $     $ x_N $  
  $ M $       $ K $  
  $ a_1 $     $ a_2 $     $ ... $     $ a_M $  

输出格式:

Print N lines. The i -th line should contain the expected value of the coordinate of the eventual position of rabbit i after K sets are performed.

The output is considered correct if the absolute or relative error is at most 109 .

输入输出样例

输入样例#1: 
3
-1 0 2
1 1
2
输出样例#1: 
-1.0
1.0
2.0
输入样例#2: 
3
1 -1 1
2 2
2 2
输出样例#2: 
1.0
-1.0
1.0
输入样例#3: 
5
0 1 3 6 10
3 10
2 3 4
输出样例#3: 
0.0
3.0
7.0
8.0
10.0
输入样例#4: 
3
-1 0 2
1 1
2
输出样例#4: 
-1.0
1.0
2.0
输入样例#5: 
3
1 -1 1
2 2
2 2
输出样例#5: 
1.0
-1.0
1.0
输入样例#6: 
5
0 1 3 6 10
3 10
2 3 4
输出样例#6: 
0.0
3.0
7.0
8.0
10.0

制約

  • 3  N  105
  • xi? は整数である。
  • xi?  10^9
  •   M  105
  • 2  aj?  N1
  • 1  K  10^18

Problem Statement

There are N rabbits on a number line. The rabbits are conveniently numbered 11 through N . The coordinate of the initial position of rabbit is xi? .

The rabbits will now take exercise on the number line, by performing sets described below. A set consists of Mjumps. The j -th jump of a set is performed by rabbit aj? ( 2  aj?  N1 ).

For this jump, either rabbit aj?1 or rabbit aj?+1 is chosen with equal probability (let the chosen rabbit be rabbit x ), then rabbit aj? will jump to the symmetric point of its current position with respect to rabbit x .

The rabbits will perform K sets in succession. For each rabbit, find the expected value of the coordinate of its eventual position after K sets are performed.

Constraints

  • 3  N  105
  • xi? is an integer.
  • xi?  10^9
  • 1  M  10^5
  • 2  aj?  N1
  • 1  K  10^18

Sample Explanation 1

うさぎ 2 がジャンプします。うさぎ 11 に関して対称な座標へジャンプすると、座標 2 へ移動します。 うさぎ 33 に関して対称な座標へジャンプすると、座標 4 へ移動します。

よって、うさぎ 2 の最終的な座標の期待値は 0.5×(2)+0.5×4=1.0 です。

Sample Explanation 2

x_ixi? は相異なるとは限りません。

Sample Explanation 4

Rabbit 22 will perform the jump. If rabbit 1 is chosen, the coordinate of the destination will be 2 . If rabbit 3 is chosen, the coordinate of the destination will be 4 . Thus, the expected value of the coordinate of the eventual position of rabbit 2 is 0.5×(2)+0.5×4=1.0 .

Sample Explanation 5

xi? may not be distinct.

 

中文描述:

??只兔子排成了一行, 第??只兔子的初始位置为????.

兔子要进行锻炼, 每一轮包含??次跳跃, 第??次是兔子 ????(2≤????≤??−1)进行跳跃, 它会等概率的选择第????−1 或第????+1只兔子 (假设为??), 然后跳到当前位置关于??的 对称点上.

这??次跳跃重复进行了??轮, 求最终每只兔子坐标的期望.

 

解题方法:

第??只兔子跳过第??只兔子之后坐标变为2∗????−????, 是线性的.

所以设????为第??只兔子位置的期望, 这个式子也成立.

进行完一次跳跃后,????变成了1/2(2????−1-xi-1)+1/2(2????+1−????)=????−1+????+1−????.

设s??=????+1−????, 那么进行一次跳跃相当于交换s??和 s??-1.

????−1 xi ????+1 -> ????−1 ????−1+xi+1-xi xi+1

s数组: xi-xi-1 xi+1-xi-> xi+1-xi xi-xi-1

我们先手动做一轮,得到交换后对应的位置。考虑dfs一遍找到形成的交换环,对每只兔子在它的环上走k步,最后再把差分的值加上就好.

代码如下:

#include<iostream>
#include<cstdio>
#include<algorithm>
#include<vector>
#define ll long long
using namespace std;

const int maxn=1e5+15;
ll n,m,k,cnt;
ll vis[maxn],s[maxn],x[maxn],num[maxn],be[maxn],p[maxn],a[maxn];
vector <ll> q[maxn];
void dfs(ll x,ll dep)//找环 
{
    num[x]=dep;vis[x]=1;be[x]=cnt;
    q[cnt].push_back(x);
    if (!vis[p[x]]) dfs(p[x],dep+1);
}
int main()
{
    scanf("%lld",&n);
    for (int i=1;i<=n;i++) scanf("%lld",x+i);
    for (int i=1;i<n;i++) s[i]=x[i+1]-x[i];//差分序列 
    scanf("%lld%lld",&m,&k);
    for (int i=1;i<n;i++) p[i]=i;
    for (int i=1;i<=m;i++) {scanf("%lld",a+i);swap(p[a[i]],p[a[i]-1]);}//一次置换的结果,记录下一次置换兔子到哪了 
    for (int i=1;i<n;i++) if (!vis[i]) {dfs(i,0);++cnt;}
    ll now=x[1];
    printf("%lld\n",now);
    for (int i=1;i<n;i++)
    {
        now+=s[q[be[i]][(num[i]+k)%q[be[i]].size()]];
        printf("%lld\n",now);
    }
    return 0;
}

 

[Atcoder Grand 006 C] Rabbit Exercise 解题报告 (期望DP)

标签:ble   sid   input   格式   size   coder   after   psu   init   

原文地址:https://www.cnblogs.com/xxzh/p/9343418.html

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