刚讲过的题
向左跳会跳到 ${a_{i-1}-(a_1-a_{i-1})}$ 即 ${2*a_{i-1}-a_i}$
向右跳会跳到 ${a_{i+1}+a_{i+1}-a_i}$ 即 ${2*a_{i+1}-a_i}$
对点$i$进行操作,期望为 ${a_{i+1}+a_{i-1}-a_i}$
暴力$10^18$ 就T飞了
考虑对期望序列差分,当序列为${a,b,c}$时,差分序列为${b-a,c-b}$
期望序列为${a,a-b+c,c}$,期望差分序列为${c-b,b-a}$
发现两个差分序列相当于交换相邻两个数
也就是做k次置换,快速幂实现即可
code
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 #include <bits/stdc++.h> 2 using namespace std; 3 #define MAXN 100010 4 int n,m,a[MAXN],ans[MAXN],res[MAXN],tmp[MAXN]; 5 long long k; 6 int main(){ 7 scanf("%d",&n); 8 for(int i=1;i<=n;++i)scanf("%d",&a[i]); 9 for(int i=1;i<n;++i)ans[i]=i; 10 scanf("%d%lld",&m,&k); 11 for(int i=1;i<=m;++i){ 12 int x; 13 scanf("%d",&x); 14 swap(ans[x],ans[x-1]); 15 } 16 for(int i=1;i<n;++i)res[i]=i; 17 while(k){ 18 if(k&1) 19 for(int i=1;i<n;++i)res[i]=ans[res[i]]; 20 for(int i=1;i<n;++i)tmp[i]=ans[ans[i]]; 21 for(int i=1;i<n;++i)ans[i]=tmp[i]; 22 k>>=1; 23 } 24 long long sum=a[1]; 25 for(int i=1;i<=n;++i){ 26 printf("%lld.0 ",sum); 27 sum+=a[res[i]+1]-a[res[i]]; 28 } 29 }