最关键的是找前这个sum[i]=sum[i]*(n-1),然后发现每个新的序列差分都不变,求出差分
然后用这个公式维护a[1],用ans[i]代表翻i次的第一项是什么,然后奇偶分情况看是加差分还是减即可
#include<iostream> #include<stdio.h> #include<string.h> #include<algorithm> #include<map> #define ll long long using namespace std; const int mod = 1e9+7; const int maxx=100005; int n,m; ll a[maxx]; ll s; ll c[maxx]; ll ans[maxx]; int main(){ int x,t; while(~scanf("%d%d",&n,&m)){ memset(c,0,sizeof(c)); memset(a,0,sizeof(a)); s=0; for (int i=1;i<=n;i++){ scanf("%lld",&a[i]); s=(a[i]+s)%mod; c[i]=(a[i]-a[1]+mod)%mod; } ll pre=s; ans[0]=a[1]; for (int i=1;i<=100001;i++){ ans[i]=(pre-a[1]+2*mod)%mod; a[1]=ans[i]; pre=pre*(n-1)%mod; } while(m--){ scanf("%d%d",&x,&t); ll anss; if (t%2==0) anss=(ans[t]+c[x])%mod; else anss=(ans[t]-c[x]+mod)%mod; printf("%lld ",anss); } } return 0; }