AT2164-[AGC006C]Rabbit Exercise【差分,倍增,数学期望】
正題
題目鏈接:https://www.luogu.com.cn/problem/AT2164
題目大意
nnn只兔子編號為1~n1\sim n1~n,第iii只在坐標軸xix_ixi?處。然后mmm次跳躍,每次給出aia_iai?,編號為aia_iai?的兔子會等概率的選取ai?1a_{i-1}ai?1?和ai+1a_{i+1}ai+1?跳躍到對稱位置。進行kkk輪,求最后每只兔子的期望位置。
3≤n≤105,1≤m≤105,1≤k≤10183\leq n\leq 10^5,1\leq m\leq 10^5,1\leq k\leq 10^{18}3≤n≤105,1≤m≤105,1≤k≤1018
解題思路
設fif_ifi?表示iii的期望位置的話,對于每次跳躍兔子xxx,它的概率就是
fx=(2fx?1?fx)+(2fx+1?fx)2=fx?1+fx+1?fxf_x=\frac{(2f_{x-1}-f_{x})+(2f_{x+1}-f_x)}{2}=f_{x-1}+f_{x+1}-f_{x}fx?=2(2fx?1??fx?)+(2fx+1??fx?)?=fx?1?+fx+1??fx?
然后這個見到這個式子就直接差分成gi=fi?fi?1g_i=f_i-f_{i-1}gi?=fi??fi?1?。
然后上面那個東西就變成了交換iii和i+1i+1i+1。
然后就是給一個交換,交換kkk次,因為kkk很大倍增搞就好了。
時間復雜度O(nlog?k)O(n\log k)O(nlogk)
code
#include<cstdio> #include<cstring> #include<algorithm> #define ll long long using namespace std; const ll N=1e5+10; ll n,m,k,d[N],ans[N],t[N]; double x[N]; signed main() {scanf("%lld",&n);for(ll i=1;i<=n;i++){scanf("%lf",&x[i]);d[i]=ans[i]=i;}scanf("%lld%lld",&m,&k);for(ll i=1;i<=m;i++){ll x;scanf("%lld",&x);swap(d[x],d[x+1]);}while(k){if(k&1){for(ll i=1;i<=n;i++)t[i]=ans[d[i]];for(ll i=1;i<=n;i++)ans[i]=t[i];}for(ll i=1;i<=n;i++)t[i]=d[d[i]];for(ll i=1;i<=n;i++)d[i]=t[i];k>>=1;}double sum=0;for(ll i=1;i<=n;i++){sum+=x[ans[i]]-x[ans[i]-1];printf("%.1lf\n",sum);}return 0; }總結
以上是生活随笔為你收集整理的AT2164-[AGC006C]Rabbit Exercise【差分,倍增,数学期望】的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: P3348-[ZJOI2016]大森林【
- 下一篇: P6378-[PA2010]Riddle