考虑转期望。

对称具有期望线性性,即我们可以关于期望位置对称。

那么一次对称操作变成 $a_i = a_{i-1} + a_{i+1} - a_i$。

考虑差分数组的变化,发现是交换了 $a_i - a_{i-1}$ 与 $a_{i+1} - a_i$。

发现 $m$ 不大,但是 $K$ 大。

发现既然是交换操作,那么可以维护一个置换,做快速幂即可。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
#include<bits/stdc++.h>
using namespace std;
#define int long long
const int maxn=1e5;
const int mod=1e9+7;
struct Node{int p[maxn+5];};
int n,m,K;
int a[maxn+5];
int b[maxn+5];
int c[maxn+5];
Node bs,res;
inline int Fpow(int x,int y){
int res=1;
for(;y;x=x*x%mod,y>>=1)
if(y&1) res=res*x%mod;
return res;
}
Node operator*(Node x,Node y){
Node z;
for(int i=1;i<n;i++)
z.p[i]=y.p[x.p[i]];
return z;
}
signed main(){
scanf("%lld",&n);
for(int i=1;i<=n;i++)
scanf("%lld",&a[i]);
for(int i=1;i<n;i++){
b[i]=a[i+1]-a[i];
bs.p[i]=i;
res.p[i]=i;
}
scanf("%lld%lld",&m,&K);
int x;
for(int i=1;i<=m;i++){
scanf("%lld",&x);
swap(bs.p[x],bs.p[x-1]);
}
int t=K;
for(;t;bs=bs*bs,t>>=1)
if(t&1) res=res*bs;
for(int i=1;i<n;i++)
c[i]=b[res.p[i]];
for(int i=2;i<=n;i++)
a[i]=a[i-1]+c[i-1];
t=Fpow(2,K%(mod-1)*m%(mod-1));
for(int i=1;i<=n;i++)
printf("%lld ",((t*a[i]%mod)+mod)%mod);
return 0;
}