1. 程式人生 > >[Atcoder Grand 006 C] Rabbit Exercise 解題報告 (期望DP)

[Atcoder Grand 006 C] Rabbit Exercise 解題報告 (期望DP)

num orange += esc nsis 當前位置 序列 exp per

題目鏈接: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 i 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)