Advertisement
ismaeil

C. Sorting Substrings2

Nov 1st, 2020
231
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 2.87 KB | None | 0 0
  1. #include <bits/stdc++.h>
  2. using namespace std;
  3.  
  4. typedef pair<int, int> ii;
  5. #define S second
  6. #define F first
  7.  
  8. vector< vector< int > > Rank;
  9. map< ii , int > Cnt;
  10. vector< ii > Seg;
  11. string s;
  12. int n ,q;
  13.  
  14. inline string Read()
  15. {
  16.     const int N = 4e5+5;
  17.     static char Buff[N];
  18.     scanf("\n%s",Buff);
  19.     return Buff;
  20. }
  21.  
  22. void CountSort(vector< int > &SA ,vector< int > &RA ,int k ,int n)
  23. {
  24.     int N = max(300,n);
  25.     vector< int > Cnt(N,0);
  26.     vector< int > tempSA(n);
  27.  
  28.     for(int i = 0 ; i < n ; i++)
  29.         Cnt[ (i + k >= n) ? 0 : RA[i + k] ] ++;
  30.  
  31.     for(int i = 0, sum = 0 ; i < N ; i++)
  32.     {
  33.         int t  = Cnt[i];
  34.         Cnt[i] = sum;
  35.         sum   += t;
  36.     }
  37.  
  38.     for(int i = 0 ; i < n ; i++)
  39.         tempSA[ Cnt[ ((SA[i] + k) < n) ? RA[ SA[i] + k ] : 0] ++ ] = SA[i];
  40.  
  41.     SA = tempSA;
  42. }
  43.  
  44. void RadixSort(vector< int > &SA ,vector< int > &RA ,int s ,int f ,int n)
  45. {
  46.     CountSort(SA ,RA ,s ,n);
  47.     CountSort(SA ,RA ,f ,n);
  48. }
  49.  
  50. vector< vector< int > > ConstructSA(string &s ,int n)
  51. {
  52.     vector< vector< int > > Rank((int)log2(n) + 2 ,vector< int >(n));
  53.  
  54.     vector< int > tempRA(n ,0) ,RA(n ,0) ,SA(n ,0);
  55.  
  56.     for(int i = 0 ; i < n ; i++) RA[i] = (int)s[i];
  57.     for(int i = 0 ; i < n ; i++) SA[i] = i;
  58.  
  59.     for(int k = 1 ; k < n && (RA[ SA[n - 1] ] != n - 1) ; k <<= 1 )
  60.     {
  61.         RadixSort(SA ,RA ,k ,0 ,n);
  62.  
  63.         int r = tempRA[ SA[0] ] = 0;
  64.         for(int i = 1 ; i < n ; i++)
  65.         {
  66.             bool flagF = (RA[ SA[i] ] == RA[ SA[i - 1] ]);
  67.             bool flagS = (RA[ (SA[i] + k) >= n ? 0 : SA[i] + k ] ==
  68.                           RA[ (SA[i - 1] + k) >= n ? 0 : SA[i - 1] + k ]);
  69.  
  70.             tempRA[ SA[i] ] = (flagF && flagS) ? r : ++r;
  71.         }
  72.  
  73.         Rank[ (int)log2(k) ] = RA = tempRA;
  74.     }
  75.  
  76.     return Rank;
  77. }
  78.  
  79. inline int Calc(int i, int j, int Len ,int Log)
  80. {
  81.     ii a = ii( Rank[Log][i] , Rank[Log][ ( i + Len - (1 << Log) ) % n ] );
  82.     ii b = ii( Rank[Log][j] , Rank[Log][ ( j + Len - (1 << Log) ) % n ] );
  83.     return (a == b ? 0 : a < b ? -1 : 1);
  84. }
  85.  
  86. inline bool Cmp(const ii &a ,const ii &b){
  87.     int LenA = a.S - a.F + 1;
  88.     int LenB = b.S - b.F + 1;
  89.     int Len  = min(LenA ,LenB);
  90.     int Log  = log2(Len);
  91.  
  92.     int Res = Calc(a.F ,b.F ,Len ,Log);
  93.  
  94.     if( Res == +1 ) return false;
  95.     if( Res == -1 ) return true;
  96.  
  97.     if( LenA > LenB ) return false;
  98.     if( LenA < LenB ) return true;
  99.  
  100.     return a < b;
  101. }
  102.  
  103. int main()
  104. {
  105.     n = (int)(s = Read() + ' ').size();
  106.  
  107.     scanf("%d" ,&q);
  108.     for(int i = 0 ; i < q ; i++)
  109.     {
  110.         int L;  scanf("%d" ,&L) ,L --;
  111.         int R;  scanf("%d" ,&R) ,R --;
  112.  
  113.         ii x = ii(L ,R);
  114.         if( Cnt[x] == 0 ) Seg.push_back(x);
  115.         Cnt[x] += 1;
  116.     }
  117.  
  118.     Rank = ConstructSA(s ,n);
  119.  
  120.     sort(Seg.begin() ,Seg.end() ,Cmp); cout << endl;
  121.  
  122.     for(auto i : Seg) while( Cnt[i]-- ) printf("%d %d\n" ,i.F + 1 ,i.S + 1);
  123. }
  124.  
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement