Cod sursa(job #25389)

Utilizator georgianaGane Andreea georgiana Data 4 martie 2007 12:25:21
Problema Kperm Scor 10
Compilator cpp Status done
Runda preONI 2007, Runda 3, Clasele 11-12 Marime 1.3 kb
#include <stdio.h>
#include <string.h>

#define mod 666013

int n,k,p[5000],rez,aux,fact[5000],nr[5000],s[5000],r[5000],rest;

int modk(int x)
{
   while (x<0) x+=k;
   while (x>=k) x-=k;
   return x;
}

void back(int t)
{
   if (t==k)
     {
        rest=0;
        for (int i=0;i<k;i++) r[i]=s[i];
        for (int i=1;i<k;i++) rest=modk(rest+p[i]);
        int ok=1;
        for (int i=k;i<=n;i++)
           {
              p[i]=modk(k-rest);
              r[p[i]]++;
              if (r[p[i]]>nr[p[i]]) { ok=0; break; }
              rest=modk(rest-p[i-k+1]+p[i]);
           }
        if (ok) rez++;
     }
   else for (int i=0;i<k;i++)
           if (s[i]<nr[i])
             {
                p[t]=i;
                s[i]++;
                back(t+1);
                s[i]--;
             }
}

int main()
{
   freopen("kperm.in","r",stdin);
   scanf("%d %d",&n,&k);

   fact[0]=1;
   for (int i=1;i<=n;i++) fact[i]=(fact[i-1]*i)%mod;

   memset(nr,0,sizeof(nr));
   for (int i=1;i<=n;i++)
      nr[modk(i)]++;
   aux=1;
   for (int i=0;i<k;i++)
      aux=(aux*fact[nr[i]])%mod;

   memset(s,0,sizeof(s));
   rest=0;
   rez=0;
   back(1);
   rez=(rez*aux)%mod;

   freopen("kperm.out","w",stdout);
   printf("%d\n",rez);
   fclose(stdout);
   return 0;
}