今天又考试了...... 这是T2。
Analysis
考试时想了一个判断质因数个数+打表的神奇方法,但没在每次输入n,m时把ans置0,50分滚粗。
看了题解才发现原来是杨辉三角+二维前缀和,果然还是我太菜了。
注意在求前缀和的时候如果这个数是0且在杨辉三角中,说明它被k求余成了0,就要把它+1。
时间复杂度O(n²)
1 #include<iostream> 2 #include<cstdio> 3 #include<cstring> 4 #include<algorithm> 5 #define maxn 2000 6 using namespace std; 7 typedef long long ll; 8 inline int read() 9 { 10 int x=0; 11 bool f=1; 12 char c=getchar(); 13 for(; !isdigit(c); c=getchar()) if(c=='-') f=0; 14 for(; isdigit(c); c=getchar()) x=(x<<3)+(x<<1)+c-'0'; 15 if(f) return x; 16 return 0-x; 17 } 18 inline void write(int x) 19 { 20 if(x<0){putchar('-');x=-x;} 21 if(x>9)write(x/10); 22 putchar(x%10+'0'); 23 } 24 ll T,k,n,m; 25 ll map[maxn+10][maxn+10],ans[maxn+10][maxn+10]; 26 int main() 27 { 28 T=read();k=read(); 29 for(int i=0;i<=maxn;i++) 30 { 31 map[i][i]=1; 32 map[i][0]=1; 33 } 34 for(int i=1;i<=maxn;i++) 35 for(int j=1;j<i;j++) 36 map[i][j]=(map[i-1][j-1]+map[i-1][j])%k; 37 for(int i=1;i<=maxn;i++) 38 for(int j=1;j<=maxn;j++) 39 { 40 ans[i][j]=ans[i-1][j]+ans[i][j-1]-ans[i-1][j-1]; 41 if(map[i][j]==0&&j<=i)ans[i][j]++; 42 } 43 while(T--) 44 { 45 n=read();m=read(); 46 write(ans[n][m]); 47 printf(" "); 48 } 49 return 0; 50 }
请各位大佬斧正(反正我不认识斧正是什么意思)