题解 AT2164 【Rabbit Exercise】

yybyyb

2018-09-20 19:58:12

Solution

无论怎么样任何一个点每次操作一定是变成$2a_{x-1}(a_{x+1})-a_x$。设$f_x$表示$x$这个点当前的期望,假设当前点要进行依次变换,那么期望为$\frac{1}{2}((2f_{x-1}-f_x)+(2f_{x+1}-f_x))=f_{x+1}+f_{x-1}-f_x$。 好的,然后进行$K$轮就不会了。怎么办呢?(当然是点开题解了啊)。闲着无聊来差分一下,设$d_i=f_i-f_{i-1}$,那么执行完一次操作之后:$d_i=(f_{i-1}+f_{i+1}-f_i)-f_{i-1}=f_{i+1}-f_i$,$d_{i+1}=f_{i+1}-(f_{i-1}+f_{i+1}-f_i)=f_i-f_{i-1}$。 好啊,一次操作等价于交换$d_i,d_{i+1}$,那么我们只要记录一下做完一轮操作之后$d_i$都到哪里去了,然后就可以倍增了。 ```cpp #include<iostream> #include<cstdio> #include<cstdlib> #include<cstring> #include<cmath> #include<algorithm> #include<vector> using namespace std; #define ll long long #define MAX 100100 inline int read() { int x=0;bool t=false;char ch=getchar(); while((ch<'0'||ch>'9')&&ch!='-')ch=getchar(); if(ch=='-')t=true,ch=getchar(); while(ch<='9'&&ch>='0')x=x*10+ch-48,ch=getchar(); return t?-x:x; } int n,x[MAX],m,d[MAX],ans[MAX],tmp[MAX];ll K; double a[MAX]; int main() { n=read(); for(int i=1;i<=n;++i)x[i]=read(); m=read();cin>>K; for(int i=1;i<=n;++i)d[i]=i,ans[i]=i; for(int i=1;i<=m;++i) { int x=read(); swap(d[x],d[x+1]); } while(K) { if(K&1) { for(int i=1;i<=n;++i)tmp[i]=ans[d[i]]; for(int i=1;i<=n;++i)ans[i]=tmp[i]; } for(int i=1;i<=n;++i)tmp[i]=d[d[i]]; for(int i=1;i<=n;++i)d[i]=tmp[i]; K>>=1; } for(int i=1;i<=n;++i)a[i]=x[ans[i]]-x[ans[i]-1]; for(int i=1;i<=n;++i)printf("%.1lf\n",a[i]+=a[i-1]); return 0; } ```