|  | 
|  | 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