传送门
这道题显然需要预处理,要不然会T飞的
70pts做法:预处理组合数,时间复杂度 O ( T ∗ m 2 ) O(T*m^{2}) O(T∗m2)
满分做法:前缀和维护,把查询的复杂度降到 O ( 1 ) O(1) O(1),总复杂度 O ( T ) O(T) O(T)
code:
#include<iostream>
#include<cstring>
#include<iostream>
using namespace std;
const int MaxN=2010;
int n,m,t,k,ans;
int c[MaxN][MaxN],sum[MaxN][MaxN];
int main()
{
// freopen("problem.in","r",stdin);
// freopen("problem.out","w",stdout);
cin>>t>>k;
c[0][0]=1%k;
for(int i=0;i<=MaxN-1;++i)
sum[0][i]=(c[0][0]==0);
for(int i=1;i<=MaxN-1;++i){
c[i][0]=1%k;
sum[i][0]=sum[i-1][0]+(c[i][0]==0);
for(int j=1;j<=i;++j){
c[i][j]=(c[i-1][j]+c[i-1][j-1])%k;
}
}
for(int i=1;i<=MaxN-1;++i){
for(int j=1;j<=MaxN-1;++j){
sum[i][j]=sum[i][j-1]+sum[i-1][j]-sum[i-1][j-1];
if(i>=j&&c[i][j]==0)
sum[i][j]++;
}
}
for(int i=1;i<=t;++i){
cin>>n>>m;
if(m>n)
m=n;
cout<<sum[n][m]<<endl;
}
return 0;
}