#include<algorithm> #include<cstdio> using namespace std; #define MAX_N 250000 int a[MAX_N], b[MAX_N], pom[MAX_N]; long long merge(int *a, int *b, int p, int q, int r); /* b to tablica pomocnicza dla procedury merge */ long long mergesort(int *a, int *b, int p, int r); int tab[250000]; int main() { int n, i, j,liczba_inwersji; long long wyn=0, wyn1=0,wyn2=0,k; scanf("%d%lld",&n,&k); if(n < 14) { for(j = 0; j < n; ++j) { tab[j] = j; } while(next_permutation(tab,tab+n)){ for(j = 0; j < n; ++j) { a[j] = tab[j]; pom[j] = tab[n- j - 1]; } //for(j = 0; j < n; ++j) printf("%d ",a[j]+1); wyn1 = mergesort(a, b, 0, n - 1); //printf("%lld ", wyn1); printf("\n"); //for(j = 0; j < n; ++j) printf("%d ",a[j]+1); wyn2 = mergesort(pom, b, 0, n - 1); //printf("%lld ", wyn2);printf("\n"); if(wyn1==wyn2) wyn++; if(wyn==k) break; } if(wyn < k) printf("NIE\n"); else { printf("TAK\n"); for(j = 0; j < n; ++j) printf("%d ",tab[j]+1); } } else{ if(n % 4==0) liczba_inwersji = n/4 *(n-1); else if(n%4 == 1) liczba_inwersji = n/4 * n; printf("NIE\n"); } return 0; } long long merge(int *a, int *b, int p, int q, int r) { /* Procedura scalajaca dwa posortowane ciagi a[p..q] z a[ q+ 1..r] przy * * wykorzystaniu tablicy pomocniczej b, a ko nkretniej jej f ragmentu * * b[p..r]. */ int i = p; int j = q + 1; int s = p; long long wyn = 0, ile_druga = 0; while (i <= q && j <= r) { if (a[i] <= a[j]) /* Wazne, zeby tu bylo d obre porow nan ie */ { b[s] = a[i]; i++; wyn += ile_druga; /* Ile juz wrzucilismy z drugiej po lo wki? */ } else { b[s] = a[j]; j++; ile_druga++; } s++; } /* Skonczyl sie ktorys z ciagow: a[p..q] lub a[q+1..r] . N al ezy ogon * * drugiego ciagu przepisac do tablicy b na pozycje s+ 1.. r. */ while (i <= q) { b[s] = a[i]; i++; s++; wyn += ile_druga; /* Ile juz wrzucilismy z drugiej p olo wk i? */ } while (j <= r) { b[s] = a[j]; j++; s++; } /* Teraz pozostaje tylko przepisac wynik-pos ortowany c iag z tablicy * * do tablicy a */ for (int it = p; it <= r; it++) a[it] = b[it]; return wyn; } long long mergesort(int *a, int *b, int p, int r) { long long wyn = 0LL; if (p == r) return wyn; int q = (p + r)/2; /* Sumujemy liczby inwersji z obu polowek */ wyn += mergesort(a, b, p, q); wyn += mergesort(a, b, q + 1, r); /* I liczbe inwersji miedzypolowkowych */ wyn += merge(a, b, p, q, r); return wyn; }
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 | #include<algorithm> #include<cstdio> using namespace std; #define MAX_N 250000 int a[MAX_N], b[MAX_N], pom[MAX_N]; long long merge(int *a, int *b, int p, int q, int r); /* b to tablica pomocnicza dla procedury merge */ long long mergesort(int *a, int *b, int p, int r); int tab[250000]; int main() { int n, i, j,liczba_inwersji; long long wyn=0, wyn1=0,wyn2=0,k; scanf("%d%lld",&n,&k); if(n < 14) { for(j = 0; j < n; ++j) { tab[j] = j; } while(next_permutation(tab,tab+n)){ for(j = 0; j < n; ++j) { a[j] = tab[j]; pom[j] = tab[n- j - 1]; } //for(j = 0; j < n; ++j) printf("%d ",a[j]+1); wyn1 = mergesort(a, b, 0, n - 1); //printf("%lld ", wyn1); printf("\n"); //for(j = 0; j < n; ++j) printf("%d ",a[j]+1); wyn2 = mergesort(pom, b, 0, n - 1); //printf("%lld ", wyn2);printf("\n"); if(wyn1==wyn2) wyn++; if(wyn==k) break; } if(wyn < k) printf("NIE\n"); else { printf("TAK\n"); for(j = 0; j < n; ++j) printf("%d ",tab[j]+1); } } else{ if(n % 4==0) liczba_inwersji = n/4 *(n-1); else if(n%4 == 1) liczba_inwersji = n/4 * n; printf("NIE\n"); } return 0; } long long merge(int *a, int *b, int p, int q, int r) { /* Procedura scalajaca dwa posortowane ciagi a[p..q] z a[ q+ 1..r] przy * * wykorzystaniu tablicy pomocniczej b, a ko nkretniej jej f ragmentu * * b[p..r]. */ int i = p; int j = q + 1; int s = p; long long wyn = 0, ile_druga = 0; while (i <= q && j <= r) { if (a[i] <= a[j]) /* Wazne, zeby tu bylo d obre porow nan ie */ { b[s] = a[i]; i++; wyn += ile_druga; /* Ile juz wrzucilismy z drugiej po lo wki? */ } else { b[s] = a[j]; j++; ile_druga++; } s++; } /* Skonczyl sie ktorys z ciagow: a[p..q] lub a[q+1..r] . N al ezy ogon * * drugiego ciagu przepisac do tablicy b na pozycje s+ 1.. r. */ while (i <= q) { b[s] = a[i]; i++; s++; wyn += ile_druga; /* Ile juz wrzucilismy z drugiej p olo wk i? */ } while (j <= r) { b[s] = a[j]; j++; s++; } /* Teraz pozostaje tylko przepisac wynik-pos ortowany c iag z tablicy * * do tablicy a */ for (int it = p; it <= r; it++) a[it] = b[it]; return wyn; } long long mergesort(int *a, int *b, int p, int r) { long long wyn = 0LL; if (p == r) return wyn; int q = (p + r)/2; /* Sumujemy liczby inwersji z obu polowek */ wyn += mergesort(a, b, p, q); wyn += mergesort(a, b, q + 1, r); /* I liczbe inwersji miedzypolowkowych */ wyn += merge(a, b, p, q, r); return wyn; } |