P6009
P6009
模拟赛考了这道题,但不知道为什么没做出来。
DP 式子的转移是很好列的,令
但是这个复杂度是过不去的,我们发现,转移写出来的矩阵只有
代码:
#include<bits/stdc++.h>
#define MOD 1000000007
#define ll long long
using namespace std;
struct Matrix{
int h;
int w;
int v[23][23];
}InvPre[50003],Pre[50003],res,ans;
Matrix operator*(Matrix A,Matrix B){
res.h=A.h;
res.w=B.w;
for(int i=1;i<=res.h;i++){
for(int j=1;j<=res.w;j++){
res.v[i][j]=0;
for(int u=1;u<=A.w;u++)res.v[i][j]=(res.v[i][j]+((ll)(A.v[i][u])*(ll)(B.v[u][j])%MOD))%MOD;
}
}
return res;
}
void print(Matrix A){
for(int i=1;i<=A.h;i++){
for(int j=1;j<=A.w;j++)printf("%d ",(A.v[i][j]+MOD)%MOD);
printf("\n");
}
return;
}
int n,k,q,w[50003],op1,op2,sum;
int main(){
scanf("%d%d",&n,&k);
for(int i=1;i<=n;i++)scanf("%d",&w[i]);
scanf("%d",&q);
Pre[0].h=Pre[0].w=InvPre[0].h=InvPre[0].w=k+1;
for(int i=1;i<=k+1;i++)Pre[0].v[i][i]=InvPre[0].v[i][i]=1;
for(int i=1;i<=n;i++){
Pre[i].h=Pre[i].w=InvPre[i].h=InvPre[i].w=k+1;
Pre[i]=Pre[i-1];
for(int u=1;u<=k+1;u++){
for(int p=1;p<=w[i]+1;p++)Pre[i].v[u][w[i]+1]=(Pre[i].v[u][w[i]+1]+Pre[i-1].v[u][p])%MOD;
}
for(int j=1;j<=k+1;j++){
for(int u=1;u<=k+1;u++){
InvPre[i].v[j][u]=(InvPre[i-1].v[j][u]-(500000004ll*(ll)(InvPre[i-1].v[w[i]+1][u])*(ll)(j<=w[i]+1))%MOD)%MOD;
}
}
}
while(q--){
scanf("%d%d",&op1,&op2);
ans.h=1;
ans.w=k+1;
for(int i=1;i<=k+1;i++)ans.v[1][i]=(int)(i==1);
ans=(ans*InvPre[op1-1]);
ans=(ans*Pre[op2]);
sum=0;
for(int i=1;i<=k+1;i++)sum=(sum+ans.v[1][i])%MOD;
sum+=MOD;
sum%=MOD;
printf("%d\n",sum);
}
return 0;
}