Advertisement
Guest User

AC

a guest
Jul 30th, 2015
215
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 5.60 KB | None | 0 0
  1. #include <stdio.h>
  2. #include <stdlib.h>
  3. #include <iostream>
  4. #include <vector>
  5. #include <algorithm>
  6. #include <stack>
  7. #include <queue>
  8. #include <math.h>
  9. #include <string.h>
  10. #include <set>
  11. #include <map>
  12. #include <iostream>
  13. #include <sstream>
  14. #define MAXN 1007
  15. #define ull unsigned long long
  16. #define INF 0xffffff
  17. #define PI acos(-1)
  18.  
  19. using namespace std;
  20.  
  21. string mapper[256];
  22. ull C[MAXN*12], pot[MAXN*12];
  23. ull B1 = 33, B2 = 79;
  24. ull fastHash[MAXN*12];
  25. int test = 1;
  26. char str[1001], bin[MAXN*12];
  27. int n,m;
  28.  
  29. //transforma int em binario
  30. string getBin(int v){
  31.         string ans = "";
  32.         if(v == 0) ans = "0";
  33.         while(v > 0){
  34.                 ans = string(1, '0'+v%2)+ans;
  35.                 v /= 2;
  36.         }
  37.         while(ans.size() < 6){
  38.                 ans = "0"+ans;
  39.         }
  40.         return ans;
  41. }
  42.  
  43. //pega o hash da janela
  44. ull getHash(int i, int j){
  45.         return fastHash[j+1] - (fastHash[i] * pot[j-i+1]) + C[j-i+1];
  46. }
  47.  
  48.  
  49. //comparator pra imprimir a resposta
  50. bool comp (vector<int> i,vector<int> j){
  51.         if(i.size() != j.size()){
  52.                 return i.size() < j.size();
  53.         }else{
  54.                 return i < j;
  55.         }
  56. }
  57.  
  58.  
  59. void printSubstring(int st){
  60.     for(int i = st; i < st+m; i++){
  61.         cout << bin[i];
  62.     }
  63.     cout << endl;
  64. }
  65.  
  66. //Testa substrig que comecam em 'a' e 'b', com tamanhos T variaveis.
  67. //Pega o maior T em comum entre as duas substrings e verifica o proximo caractere
  68. bool lex(int a, int b){
  69.         int lo = 0, hi = m;
  70.         while(lo < hi){
  71.                 int T = (lo+hi+1) / 2;
  72.                 if(getHash(a,a+T-1) == getHash(b,b+T-1)){
  73.                         lo = T;
  74.                 }else{
  75.                         hi = T-1;
  76.                 }
  77.         }
  78.         //printSubstring(a) ;printSubstring(b);
  79.         //cout << lo << " " << endl;
  80.         if(bin[a+lo] < bin[b+lo]){
  81.             return 0;
  82.         }else{
  83.             return 1;
  84.         }
  85. }
  86.  
  87. /*
  88.     mapper -> guarda os numeros em binario no formatro string
  89.     bin -> guarda a string ja em formato binario
  90.     fastHash -> guarda hash da string atual
  91. */
  92.  
  93.  
  94. int main(void){
  95.         //freopen("in.in", "r", stdin);
  96.         int idx = 0;
  97.         pot[0] = C[0] = 1;
  98.         for(int i = 0; i < MAXN; i++){
  99.                 pot[i+1] = pot[i] * B1;
  100.                 C[i+1] = C[i] * B2;
  101.         }
  102.         for(int i = 'A'; i <= 'Z'; i++){
  103.                 mapper[i] = getBin(idx++);
  104.         }
  105.         for(int i = 'a'; i <= 'z'; i++){
  106.                 mapper[i] = getBin(idx++);
  107.         }
  108.         for(int i = '0'; i <= '9'; i++){
  109.                 mapper[i] = getBin(idx++);
  110.         }
  111.         mapper['+'] = getBin(idx++);
  112.         mapper['/'] = getBin(idx++);
  113.  
  114.         while(scanf("%d", &n) && n != 0){
  115.                 map<string, vector<int> > ans;
  116.                 for(int i = 0; i < n; i++){
  117.                         //lendo a string em base64
  118.                         scanf(" %s", str);
  119.                         int size = strlen(str);
  120.                         m = size*6;
  121.                         int pos = 0;
  122.                         //Construindo a string binaria e ja prcessando o hash
  123.                         for(int j = 0; j < size; j++){
  124.                                 for(int k = 0; k < mapper[str[j]].size(); k++){
  125.                                         bin[pos] = mapper[str[j]][k];
  126.                                         fastHash[pos+1] = mapper[str[j]][k] + fastHash[pos] * B1;
  127.                                         pos++;
  128.                                 }
  129.                         }
  130.                         //Duplicando a string binaria e ja prcessando o hash
  131.                         for(int j = 0; j < size; j++){
  132.                                 for(int k = 0; k < mapper[str[j]].size(); k++){
  133.                                         bin[pos] = mapper[str[j]][k];
  134.                                         fastHash[pos+1] = mapper[str[j]][k] + fastHash[pos] * B1;
  135.                                         pos++;
  136.                                 }
  137.                         }
  138.                         int lower = 0;
  139.                         //pegando a menor, considerando que cada substring comeca em j e tem tamanho m
  140.                         for(int j = 1; j + m < m*2; j++){
  141.                                 if(lex(lower,j) == 1){
  142.                                     lower = j;
  143.                                 }
  144.                         }
  145.                         //map pra agrupar os fingerprints
  146.                         string tmpAns = "";
  147.                         for(int j = lower; j < lower+m; j++) tmpAns += string(1, bin[j]);
  148.                         //cout << tmpAns << endl;
  149.                         if(ans.find(tmpAns) == ans.end()){
  150.                                 ans[tmpAns] = vector<int>(1,i);
  151.                         }else{
  152.                                 ans[tmpAns].push_back(i);
  153.                          }
  154.                 }
  155.                 printf("Case %d:\n", test++);
  156.                 vector<vector<int> > groups;
  157.                 for(map<string, vector<int> >::iterator it = ans.begin(); it != ans.end(); it++){
  158.                         sort(it->second.begin(), it->second.end());
  159.                         groups.push_back(it->second);
  160.                 }
  161.                 sort(groups.begin(), groups.end(), comp);
  162.                 for(int i = 0; i < groups.size(); i++){
  163.                         printf("%d",1+groups[i][0]);
  164.                         for(int j = 1; j < groups[i].size(); j++){
  165.                                 printf(" %d", 1+groups[i][j]);
  166.                         }
  167.                         printf("\n");
  168.                 }
  169.         }
  170.         return 0;
  171. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement