|
| 1 | +#include <bits/stdc++.h> |
| 2 | +using namespace std; |
| 3 | +typedef long long ll; |
| 4 | +const ll MOD1 = 1e9 + 9; |
| 5 | +const ll prime1 = 999983; |
| 6 | +const ll MOD2 = 1e9 + 7; |
| 7 | +const ll prime2 = 999979; |
| 8 | +const ll invprime1 = 943912055; |
| 9 | +const ll invprime2 = 672490127; |
| 10 | +const ll MOD3 = 1e9 + 21; |
| 11 | +const ll prime3 = 1e6 + 3; |
| 12 | +const ll invprime3 = 801275613LL; |
| 13 | +const int MAXN = 1002; |
| 14 | +vector<int> resposta,conversao; |
| 15 | +int N,vetor[MAXN][MAXN],tamanho[MAXN],inicio[MAXN],logaritmo2[MAXN]; |
| 16 | +ll hash1[MAXN][MAXN],pot1[MAXN],invpot1[MAXN],hash2[MAXN][MAXN],pot2[MAXN],invpot2[MAXN],hash3[MAXN][MAXN],pot3[MAXN],invpot3[MAXN]; |
| 17 | +inline int igualdade2(int p1,int ini1,int fim1,int p2,int ini2,int fim2){ |
| 18 | + for(int i1 = ini1, i2 = ini2;i1 <= fim1;i1++,i2++){ |
| 19 | + if(vetor[p1][i1] != vetor[p2][i2]) return 0; |
| 20 | + } |
| 21 | + return 1; |
| 22 | +} |
| 23 | +inline ll get_hash1(int idx,int a,int b){ |
| 24 | + ll val = (hash1[idx][b] - hash1[idx][a-1])*invpot1[a-1]; |
| 25 | + val %= MOD1; |
| 26 | + if(val < 0) val += MOD1; |
| 27 | + return val; |
| 28 | +} |
| 29 | +inline ll get_hash2(int idx,int a,int b){ |
| 30 | + ll val = (hash2[idx][b] - hash2[idx][a-1])*invpot2[a-1]; |
| 31 | + val %= MOD2; |
| 32 | + if(val < 0) val += MOD2; |
| 33 | + return val; |
| 34 | +} |
| 35 | +inline ll get_hash3(int idx,int a,int b){ |
| 36 | + ll val = (hash3[idx][b] - hash3[idx][a-1])*invpot3[a-1]; |
| 37 | + val %= MOD3; |
| 38 | + if(val < 0) val += MOD3; |
| 39 | + return val; |
| 40 | +} |
| 41 | +inline int igualdade(int p1,int ini1,int fim1,int p2,int ini2,int fim2){ |
| 42 | + //int flag = igualdade2(p1,ini1,fim1,p2,ini2,fim2); |
| 43 | + if(get_hash1(p1,ini1,fim1) != get_hash1(p2,ini2,fim2)){ |
| 44 | + //if(flag) printf("Falso negativo %d %d %d %d %d %d hash1\n",p1,ini1,fim1,p2,ini2,fim2); |
| 45 | + return 0; |
| 46 | + } |
| 47 | + //if(get_hash2(p1,ini1,fim1) != get_hash2(p2,ini2,fim2)){ |
| 48 | + //if(flag) printf("Falso negativo %d %d %d %d %d %d hash2\n",p1,ini1,fim1,p2,ini2,fim2); |
| 49 | + // return 0; |
| 50 | + //} |
| 51 | + //if(get_hash3(p1,ini1,fim1) != get_hash3(p2,ini2,fim2)){ |
| 52 | + //if(flag) printf("Falso negativo %d %d %d %d %d %d hash3\n",p1,ini1,fim1,p2,ini2,fim2); |
| 53 | + //return 0; |
| 54 | + //} |
| 55 | + //if(!flag){ |
| 56 | + //printf("Falso positivo %d %d %d %d %d %d\n",p1,ini1,fim1,p2,ini2,fim2); |
| 57 | + //printf("%lld %lld hash1\n",get_hash1(p1,ini1,fim1),get_hash1(p2,ini2,fim2)); |
| 58 | + //printf("%lld %lld hash2\n",get_hash2(p1,ini1,fim1),get_hash2(p2,ini2,fim2)); |
| 59 | + //printf("%lld %lld hash3\n",get_hash3(p1,ini1,fim1),get_hash3(p2,ini2,fim2)); |
| 60 | + //} |
| 61 | + return 1; |
| 62 | +} |
| 63 | +bool comp(int p1,int p2){ |
| 64 | + if(vetor[p1][inicio[p1]] != vetor[p2][inicio[p2]]) return vetor[p1][inicio[p1]] < vetor[p2][inicio[p2]]; |
| 65 | + int tam1 = tamanho[p1] - inicio[p1] + 1; |
| 66 | + int tam2 = tamanho[p2] - inicio[p2] + 1; |
| 67 | + int tam = min(tam1,tam2); |
| 68 | + int atual = 0; |
| 69 | + for(int i = logaritmo2[tam];i>=0;i--){ |
| 70 | + int novo = atual + (1 << i); |
| 71 | + if(novo <= tam && igualdade(p1,inicio[p1],inicio[p1]+novo-1,p2,inicio[p2],inicio[p2]+novo-1)){ |
| 72 | + atual = novo; |
| 73 | + } |
| 74 | + } |
| 75 | + if(atual == tam) return tam1 > tam2; |
| 76 | + return vetor[p1][inicio[p1]+atual] < vetor[p2][inicio[p2]+atual]; |
| 77 | +} |
| 78 | +inline bool heap_comp(int p1,int p2){ |
| 79 | + return !comp(p1,p2); |
| 80 | +} |
| 81 | +int main(){ |
| 82 | + cin.tie(0);cout.tie(0);ios_base::sync_with_stdio(0); |
| 83 | + cin >> N; |
| 84 | + pot1[0] = invpot1[0] = pot2[0] = invpot2[0] = pot3[0] = invpot3[0] = 1; |
| 85 | + for(int i = 1;i<MAXN;i++){ |
| 86 | + pot1[i] = (pot1[i-1]*prime1) % MOD1; |
| 87 | + invpot1[i] = (invpot1[i-1]*invprime1) % MOD1; |
| 88 | + //pot2[i] = (pot2[i-1]*prime2) % MOD2; |
| 89 | + //invpot2[i] = (invpot2[i-1]*invprime2) % MOD2; |
| 90 | + //pot3[i] = (pot3[i-1]*prime3) % MOD3; |
| 91 | + //invpot3[i] = (invpot3[i-1]*invprime3) % MOD3; |
| 92 | + logaritmo2[i] = logaritmo2[i/2] + 1; |
| 93 | + } |
| 94 | + for(int i = 1;i<=N;i++){ |
| 95 | + cin >> tamanho[i]; |
| 96 | + inicio[i] = 1; |
| 97 | + for(int j = 1;j<=tamanho[i];j++){ |
| 98 | + cin >> vetor[i][j]; |
| 99 | + conversao.push_back(vetor[i][j]); |
| 100 | + } |
| 101 | + } |
| 102 | + sort(conversao.begin(),conversao.end()); |
| 103 | + conversao.erase(unique(conversao.begin(),conversao.end()),conversao.end()); |
| 104 | + for(int i = 1;i<=N;i++){ |
| 105 | + for(int j = 1;j<=tamanho[i];j++){ |
| 106 | + vetor[i][j] = lower_bound(conversao.begin(),conversao.end(),vetor[i][j]) - conversao.begin() + 1; |
| 107 | + hash1[i][j] = (hash1[i][j-1] + vetor[i][j]*pot1[j]) % MOD1; |
| 108 | + //hash2[i][j] = (hash2[i][j-1] + vetor[i][j]*pot2[j]) % MOD2; |
| 109 | + //hash3[i][j] = (hash3[i][j-1] + vetor[i][j]*pot3[j]) % MOD3; |
| 110 | + } |
| 111 | + } |
| 112 | + priority_queue<int, vector<int>, bool(*)(int,int) > pq(heap_comp); |
| 113 | + for(int i = 1;i<=N;i++) pq.push(i); |
| 114 | + while(!pq.empty()){ |
| 115 | + int davez = pq.top(); |
| 116 | + pq.pop(); |
| 117 | + resposta.push_back(vetor[davez][inicio[davez]]); |
| 118 | + inicio[davez]++; |
| 119 | + if(inicio[davez] <= tamanho[davez]) pq.push(davez); |
| 120 | + } |
| 121 | + for(int i : resposta) cout << conversao[i-1] << " "; |
| 122 | + cout << endl; |
| 123 | + return 0; |
| 124 | +} |
0 commit comments