Codechef : Sereja and Equality/SEAEQ (DP)
阿新 • • 發佈:2018-12-14
題解: 普及組DP。
#include <bits/stdc++.h>
using namespace std;
const int RLEN=1<<18|1;
inline char nc() {
static char ibuf[RLEN],*ib,*ob;
(ib==ob) && (ob=(ib=ibuf)+fread(ibuf,1,RLEN,stdin));
return (ib==ob) ? -1 : *ib++;
}
inline int rd() {
char ch=nc(); int i=0,f=1;
while(!isdigit (ch)) {if(ch=='-')f=-1; ch=nc();}
while(isdigit(ch)) {i=(i<<1)+(i<<3)+ch-'0'; ch=nc();}
return i*f;
}
const int N=5e2+50, M=500, mod=1e9+7;
inline int add(int x,int y) {return (x+y>=mod) ? (x+y-mod) : (x+y);}
inline int dec(int x,int y) {return (x-y<0) ? (x-y+mod) : (x-y);}
inline void up(int &x,int y) {x=add(x,y);}
inline void dn(int &x,int y) {x=dec(x,y);}
inline int mul(int x,int y) {return (long long)x*y%mod;}
inline int power(int a,int b,int rs=1) {for(;b;b>>=1,a=mul(a,a)) if(b&1) rs=mul(rs,a); return rs;}
struct Combin {
int fac[N],ifac[N];
Combin() {
fac[ 0]=1;
for(int i=1;i<=M;i++) fac[i]=mul(fac[i-1],i);
ifac[M]=power(fac[M],mod-2);
for(int i=M-1;~i;i--) ifac[i]=mul(ifac[i+1],i+1);
}
inline int C(int a,int b) {return mul(fac[a],mul(ifac[b],ifac[a-b]));}
} C;
int f[N][N*N/2];
inline void pre_calc() {
f[1][0]=1;
for(int i=1;i<=M;i++)
for(int j=0;j<=i*(i-1)/2;j++) {
if(j) up(f[i][j],f[i][j-1]);
up(f[i+1][j],f[i][j]);
dn(f[i+1][j+i+1],f[i][j]);
}
for(int i=1;i<=M;i++)
for(int j=1;j<=i*(i-1)/2;j++) up(f[i][j],f[i][j-1]);
}
inline int P(int x) {return mul(x,x);}
int main() {
pre_calc();
for(int T=rd();T;T--) {
int ans=0, n=rd(), m=rd();
for(int i=1;i<=n;i++) {
int rs=P(C.C(n,i));
rs=mul(rs,P(C.fac[n-i]));
rs=mul(rs,n-i+1);
up(ans,mul(rs,f[i][min(m,i*(i-1)/2)]));
}
printf("%d\n",ans);
}
}