Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- /* cf 403D */
- /* differences between any pairs should be distinct..so instead of k pairs we can assume k distinct numbers..bi - ai = ci..sum of all ci <= n..why ? coz otherwise we have to take a pair that is greater than 1000... as 1 + 2 +....+ 45 >1000..
- so if k > 44 then ans will b zero...
- we will recursively iterate all numbers and try to take how many ways are there to divide i into k parts..here i is from 1 to n...but now the most interesting part comes here..we actually can increase the difference between any segments...but sum of all should b n...so stars and bars comes here...
- */
- ll f[500];int dp[1001][50][1001];ll ncr[1001][50],ans[1001][50];
- ll NCR(int n,int r){
- if(n==r)return 1;
- if(r==1)return n;
- if(n<r)return 0;
- if(ncr[n][r])return ncr[n][r];
- return ncr[n][r] =( NCR(n-1,r-1) + NCR(n-1,r) )%mod;
- }
- void pre(){
- f[0] = 1;
- for(int i = 1;i<450;i++)f[i] = (f[i-1] * i )%mod;
- }
- ll stars_and_bars(int n,int k){
- return NCR(n+k-1,k-1);
- }
- int giveres(int n,int k,int p){
- if(n==0&&k==0)return 1;
- if(n==0||k==0||p>n)return 0;
- int &ret = dp[n][k][p];
- if(ret!=-1)return ret;
- ret = 0;
- ret+=giveres(n-p,k-1,p+1);
- ret %= mod;
- ret+=giveres(n,k,p+1);
- ret %= mod;
- return ret;
- }
- ll solve(int n,int k){
- if(ans[n][k]!=-1)return ans[n][k];
- ll ret = 0;
- for(int i = n;i>=1;i--){
- ret += ((ll)giveres(i,k,1) * stars_and_bars(n-i,k+1) )%mod;
- ret %= mod;
- }
- return ans[n][k] = (ret * f[k])%mod;
- }
- int main()
- {
- booster()
- // read("input.txt");
- pre();
- mem(dp,-1);
- mem(ans,-1);
- int t;
- cin>>t;
- while(t--){
- int n,k;
- cin>>n>>k;
- if(k>44)cout<<0<<endl;
- else
- cout<<solve(n,k)<<endl;
- }
- return 0;
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement