Cod sursa(job #129122)

Utilizator tErMyAndrei Panturu tErMy Data 28 ianuarie 2008 17:54:43
Problema NKPerm Scor 100
Compilator cpp Status done
Runda Arhiva de probleme Marime 3.53 kb
 #include <stdio.h>  
 #include <string>  
 #include <map>  
   
 using namespace std;  
   
 #define ll long long  
   
 #define maxk 110  
 #define maxl 6  
 #define maxn 21  
 #define stop 1LL<<55  
   
 map <int, ll> c;  
 int n,m,N;  
 int a[maxk],b[maxn];  
 int cate[maxl];  
 ll sol;  
   
 inline int convert(int x)  
 {  
     int rez=0,i;  
     for (i=0;i<=m;i++) rez = rez * (n+1) + cate[i];  
     rez = rez * (n+1) + x;  
   
     return rez;  
 }  
   
 ll solve(int i)  
 {  
     int j,x = convert(i);  
   
     ll rez = 0;  
   
     if (c.find(x)!=c.end()) return c[x];  
   
     if (cate[m] == n) rez = 1;  
     else for (j=0;j<m;j++)  
             if (cate[j])  
             {  
                 cate[j]--;  
                 cate[j+1]++;  
   
                 ll aux = solve(j+1);  
   
                 if (j!=i) rez += 1LL * (cate[j]+1) * aux;  
                 else rez += 1LL * cate[j] * aux;  
   
                 cate[j]++;  
                 cate[j+1]--;  
   
                 if (rez >= stop)   
                 {  
                     rez = stop;  
                     break;  
                 }  
             }  
   
     c[x] = rez;  
     return rez;  
 }  
   
 int main()  
 {  
     freopen("nkperm.in","r",stdin);  
     freopen("nkperm.out","w",stdout);  
   
     int T,i,j;  
     char op;  
     ll x,aux;  
   
     scanf("%d %d %d ",&n,&m,&T);  
   
     N = n * m;  
   
     while (T)  
     {  
         scanf("%c ",&op);  
         if (op=='A')  
         {  
             for (i=1;i<=N;i++) scanf("%d ",&a[i]);     
   
             memset(cate,0,sizeof(cate));  
             memset(b,0,sizeof(b));  
   
             sol = 1;  
             cate[0] = n;  
   
             for (i=1;i<=N;i++)  
             {  
                 for (j=1;j<a[i];j++)   
                     if (j!=a[i-1] && b[j]<m)  
                     {  
                         cate[b[j]]--;  
                         b[j]++;  
                         cate[b[j]]++;  
                          
                         sol += solve(b[j]);  
   
                         cate[b[j]]--;  
                         b[j]--;  
                         cate[b[j]]++;  
                     }  
   
                 cate[b[a[i]]]--;  
                 b[a[i]]++;  
                 cate[b[a[i]]]++;  
             }  
             printf("%lld\n",sol);  
         }  
         else {  
                  memset(b,0,sizeof(b));  
                  memset(cate,0,sizeof(cate));  
   
                  cate[0] = n;  
   
                  scanf("%lld ",&x);  
   
                  for (i=1;i<=N;i++)  
                  {  
                     for (j=1;j<=n;j++)  
                         if (j != a[i-1] && b[j]<m)  
                         {  
                             cate[b[j]]--;  
                             b[j]++;  
                             cate[b[j]]++;  
   
                             a[i] = j;  
                             aux = solve(b[j]);  
   
                             if (aux>=x) break;  
                             else x -= aux;  
   
                             cate[b[j]]--;  
                             b[j]--;  
                             cate[b[j]]++;  
                         }  
                  }  
   
                  for (i=1;i<=N;i++) printf("%d ",a[i]);  
                  printf("\n");  
              }  
       
   
         T--;  
     }  
   
     return 0;  
 }