【题解】Luogu AT2164 Rabbit Exercise

刚讲过的题

向左跳会跳到 ${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

 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 }
View Code
原文地址:https://www.cnblogs.com/gengyf/p/11669972.html