Pagini recente » Cod sursa (job #22949) | Cod sursa (job #3264025) | IAP #5: Open surse | Cod sursa (job #1361663) | Cod sursa (job #2401138)
#include <iostream>
#include <fstream>
#include <cmath>
using namespace std;
const int nmax=1030;
const int mod=10007;
const double pi=acos(-1.0);
int fact[nmax],sol[nmax];
int dp[nmax][nmax],c[nmax][nmax];
int o[nmax];
int n,k,i,j,ind,lim;
struct cpx
{
long double re,im;
}p1[nmax],p2[nmax],p3[nmax],root,put,U,V;
cpx operator +(cpx unu,cpx doi) {return {unu.re+doi.re,unu.im+doi.im};}
cpx operator *(cpx unu,cpx doi) {return {unu.re*doi.re-unu.im*doi.im,unu.re*doi.im+unu.im*doi.re};}
cpx operator -(cpx unu,cpx doi) {return {unu.re-doi.re,unu.im-doi.im};}
void prc()
{
fact[0]=1;
for(i=1;i<=n;i++)
fact[i]=(fact[i-1]*i)%mod;
for(i=0;i<=n;i++)
for(j=0;j<=i;j++)
{
if(!j) c[i][j]=1;
else c[i][j]=(c[i-1][j-1]+c[i-1][j])%mod;
}
}
void fft(cpx v[],long double rev)
{
double L;
int l;
for(i=0;i<lim;i++)
if(i<o[i])
swap(v[i],v[o[i]]);
for(l=1;l<lim;l*=2)
{
L=2*l;
root={cos(2*pi/L),rev*sin(2*pi/L)};
for(i=0;i<lim;i+=2*l)
{
put={1,0};
for(j=0;j<l;j++)
{
U=v[i+j];V=v[i+j+l];
v[i+j]=U+V*put;
v[i+j+l]=U-V*put;
put=put*root;
}
}
}
if(rev==-1)
{
L=lim;
for(i=0;i<lim;i++)
v[i].re/=L,v[i].im/=L;
}
}
bool tr=0;
void multiplica(int a[],int b[],int c[])
{
for(i=0;i<lim;i++)
p1[i].re=a[i],p1[i].im=0;
if(!tr)
for(i=0;i<lim;i++)
p2[i].re=b[i],p2[i].im=0;
fft(p1,1);
if(!tr)
fft(p2,1);
for(i=0;i<lim;i++)
p3[i]=p1[i]*p2[i];
fft(p3,-1);
for(i=0;i<lim;i++)
{
c[i]=round(p3[i].re);
}
}
int main()
{
ifstream f("permutari2.in");
ofstream g("permutari2.out");
f>>n>>k;
prc();
dp[0][0]=1;lim=1024;
for(i=0;i<10;i++)
for(j=0;j<lim;j++)
if(((1<<i)&j))
o[j]|=(1<<(9-i));
fact[0]=0;
for(int ii=1;ii<=n;ii++)
{
multiplica(dp[ii-1],fact,dp[ii]);
for(int j=n+1;j<lim;j++)
dp[ii][j]=0;
for(int j=1;j<=n;j++)
dp[ii][j]%=mod;
sol[ii]=dp[ii][n];
tr=1;
}
for(i=n;i>=k;i--)
for(j=i+1;j<=n;j++)
{
sol[i]=(sol[i]-sol[j]*c[j-1][i-1])%mod;
if(sol[i]<0)
sol[i]+=mod;
}
g<<sol[k];
return 0;
}