https://atcoder.jp/contests/agc006/tasks/agc006_c
明明在暑假已经见过了置换快速幂,明明已经领悟了期望的良好的性质,直接用期望算可以得到pi=p_i+1+p_i-1-p_i
两件美好的事叠加在一起,do si de,还是不会做呢
这题关键是想到令每个位置当前所在的坐标的期望为pi,然后依次交换以后pi=p_i+1+p_i-1-p_i,然而这个式子并不好办,还是跟顺序有关
然后我们令bi=p_i-p_i-1,代入以后发现依次操作实际上是交换了b_i和b_i+1,由题目可知a1和an总是不变的,那么只有中间的数字的坐标期望在边
于是我们就可以把bi进行置换快速幂了复杂度就是O(nlogk)的
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int maxl=3e5+10;
int n,m,cnt,tot,cas;ll k;
int a[maxl],ans[maxl],b[maxl],tmp[maxl];
bool vis[maxl];
char s[maxl];
inline void prework()
{
scanf("%d",&n);
for(int i=1;i<=n;i++)
scanf("%d",&a[i]);
scanf("%d%lld",&m,&k);
for(int i=1;i<=n;i++)
b[i]=i;
for(int i=1;i<=m;i++)
{
int x;scanf("%d",&x);
swap(b[x],b[x+1]);
}
}
inline void qp(ll k)
{
for(int i=2;i<=n;i++)
ans[i]=a[i]-a[i-1];
while(k)
{
if(k&1)
{
for(int i=1;i<=n;i++)
tmp[i]=ans[b[i]];
for(int i=1;i<=n;i++)
ans[i]=tmp[i];
}
for(int i=1;i<=n;i++)
tmp[i]=b[b[i]];
for(int i=1;i<=n;i++)
b[i]=tmp[i];
k>>=1;
}
}
inline void mainwork()
{
qp(k);
}
inline void print()
{
ll x=a[1];
for(int i=1;i<=n;i++)
{
x+=ans[i];
printf("%lld\n",x);
}
}
int main()
{
int t=1;
//scanf("%d",&t);
for(cas=1;cas<=t;cas++)
{
prework();
mainwork();
print();
}
return 0;
}