這個題。
畫出這樣一個矩形,設左邊第行第0列的數爲,上邊第列第行的數爲,就可以得到
那麼可以發現交換兩行和兩列,只需要單點修改這兩個數組即可。
次前綴和,考慮一個在次前綴和後的這個矩形中總共貢獻了多少答案。
拆開變成和有關的式子:
後面那個
所以可以進一步化簡爲:
考慮如何維護
差分轉化爲維護
求出的係數,這個可以預處理。
然後只需要樹狀數組維護求出即可計算出
時間複雜度
#include<bits/stdc++.h>
#define maxn 100505
#define mod 1000000007
using namespace std;
int n,m,l[maxn],u[maxn],fac[maxn],inv[maxn],invf[maxn];
int tl[11][maxn],tu[11][maxn],P[11][11][11];
int add(int a){ return a >= mod ? a - mod : a; }
void upd(int *tr,int u,int v){ for(;u<maxn;u+=u&-u) tr[u] = add(tr[u] + v); }
int qry(int *tr,int u){ int r=0;for(;u;u-=u&-u) r=add(r+tr[u]);return r; }
int C(int a,int b){ if(a<0||b<0||a-b<0) return 0;return fac[a] * 1ll * invf[b] % mod * invf[a-b]%mod; }
int main(){
freopen("1.in","r",stdin);
freopen("1.out","w",stdout);
int Q;
scanf("%d%d%d",&n,&m,&Q);
for(int i=1;i<=n;i++){
l[i] = 1ll * (i-1) * m % mod;
for(int j=0,p=l[i];j<=10;j++,p=1ll*p*i%mod)
upd(tl[j],i,p);
}
for(int i=1;i<=m;i++){
u[i] = i;
for(int j=0,p=u[i];j<=10;j++,p=1ll*p*i%mod)
upd(tu[j],i,p);
}
fac[0] = fac[1] = inv[0] = inv[1] = invf[0] = invf[1] = 1;
for(int i=2;i<maxn;i++) fac[i] = 1ll * fac[i-1] * i % mod,
inv[i] = 1ll * (mod - mod / i) * inv[mod % i] % mod,
invf[i] = 1ll * invf[i-1] * inv[i] % mod;
P[0][0][0] = 1;
for(int i=1;i<=10;i++)
for(int j=0;j<=i;j++)
for(int k=0;k<=i;k++){
if(j) P[i][j][k] = add(P[i][j][k] + P[i-1][j-1][k]);
if(k) P[i][j][k] = add(P[i][j][k] + mod - P[i-1][j][k-1]);
P[i][j][k] = (P[i][j][k] + 1ll * P[i-1][j][k] * i) % mod;
P[i][j][k] = 1ll * P[i][j][k] * inv[i] % mod;
}
char ch[2];
for(int a,b,c,d,K;Q--;){
scanf("%s%d%d",ch,&a,&b);
if(ch[0] == 'R'){
int t = add(l[a] - l[b] + mod);
for(int j=0,p=t;j<=10;j++,p=1ll*p*b%mod)
upd(tl[j],b,p);
for(int j=0,p=mod-t;j<=10;j++,p=1ll*p*a%mod)
upd(tl[j],a,p);
swap(l[a],l[b]);
}
if(ch[0] == 'C'){
int t = add(u[a] - u[b] + mod);
for(int j=0,p=t;j<=10;j++,p=1ll*p*b%mod)
upd(tu[j],b,p);
for(int j=0,p=mod-t;j<=10;j++,p=1ll*p*a%mod)
upd(tu[j],a,p);
swap(u[a],u[b]);
}
if(ch[0] == 'Q'){
scanf("%d%d%d",&c,&d,&K);
swap(b,c);
static int ar[11]={};
int ans = 0 , sml = 0 , smr = 0;
for(int j=0;j<=K;j++){
ar[j] = add(qry(tl[j],b) - qry(tl[j],a-1) + mod);
for(int k=0,p=1;k<=K;k++,p=1ll*p*b%mod) if(P[K][k][j])
sml = (sml + 1ll * P[K][k][j] * ar[j] % mod * p) % mod;
}
ans = (ans + sml * 1ll * C(d-c+K+1,K+1)) % mod;
for(int j=0;j<=K;j++){
ar[j] = add(qry(tu[j],d) - qry(tu[j],c-1) + mod);
for(int k=0,p=1;k<=K;k++,p=1ll*p*d%mod) if(P[K][k][j])
smr = (smr + 1ll * P[K][k][j] * ar[j] % mod * p) % mod;
}
ans = (ans + smr * 1ll * C(b-a+K+1,K+1)) % mod;
printf("%d\n",(ans+mod)%mod);
}
}
}