Advertisement
RaFiN_

pallindromic tree

May 17th, 2019
203
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 2.95 KB | None | 0 0
  1. /* pallindromic tree */
  2.  
  3. //when indx based calcu is required
  4.  
  5. ll tree[MAX][30],idx,link[MAX],len[MAX],t,pree[MAX][30],cnt;char s[MAX];ll occ[MAX];ll ans1[MAX],ans2[MAX];ll f[MAX],e[MAX];
  6.  
  7. void initialize()
  8. {
  9.     len[1] = -1;
  10.     len[2] = 0;
  11.     link[1] = 1;
  12.     link[2] = 1;
  13.     t = idx = 2;
  14.     mem(tree,0);
  15.     mem(occ,0);
  16. }
  17.  
  18. int extend(int p){
  19.     int save;
  20.     while(s[p - len[t] - 1] != s[p]) t = link[t];
  21.     int x = link[t], c = s[p] - 'a';
  22.     while(s[p - len[x] - 1] != s[p]) x = link[x];
  23.     if(!tree[t][c]) {
  24.         tree[t][c] = ++idx;
  25.         save = idx;
  26.         len[idx] = len[t] + 2;
  27.         link[idx] = len[idx] == 1 ? 2 : tree[x][c];
  28.     }
  29.     else {
  30.         save = tree[t][c];
  31.     }
  32.      t = tree[t][c];
  33.      return save;
  34. }
  35.  
  36.  
  37.  
  38. int main()
  39. {
  40.     //booster()
  41.     ///read("input.txt");
  42.  
  43.    
  44.         scanf(" %s",s+1);
  45.        
  46.         initialize();int l = strlen(s+1);
  47.         for(int i = 1;i<=l;i++){
  48.             int x = extend(i);
  49.             f[i] = x;
  50.         }
  51.        
  52.         for(int i = 3;i<=idx;i++){
  53.             occ[i]+=occ[link[i]] + 1;
  54.         }
  55.         for(int i = 1;i<=l;i++){
  56.             int x = f[i];
  57.             ans1[i] = occ[x];
  58.         }
  59.         string s2 = s+1;
  60.         reverse(all(s2));
  61.  
  62.         for(int i = 1;i<=l;i++)s[i] = s2[i-1];
  63.         initialize();
  64.         for(int i = 1;i<=l;i++){
  65.             int x = extend(i);
  66.             e[i] = x;
  67.         }
  68.         for(int i = 3;i<=idx;i++){
  69.             occ[i]+=occ[link[i]] + 1;
  70.         }
  71.         for(int i = 1;i<=l;i++){
  72.             ans2[l-i+1] = occ[e[i]];
  73.         }
  74.  
  75.         //for(int i = 1;i<=l;i++)cout<<ans1[i]<<" "<<ans2[i]<<endl;
  76.  
  77.         for(int i = l-1;i>=1;i--)ans2[i]+=ans2[i+1];
  78.  
  79.         ull ans = 0;
  80.         for(int i = 1;i<=l-1;i++){
  81.             //if(ans1[i]&&ans2[i+1])
  82.             ans+=(ans1[i] * ans2[i+1]);
  83.         }
  84.         cout<<ans<<endl;
  85.  
  86.  
  87.  
  88.     return 0;
  89. }
  90.  
  91.  
  92.  
  93. // when pallindromic substring based calcu is required
  94.  
  95. int tree[MAX][30],idx,link[MAX],len[MAX],t,pree[MAX][30],cnt;char s[MAX];ll occ[MAX];
  96.  
  97. void initialize()
  98. {
  99.     len[1] = -1;
  100.     len[2] = 0;
  101.     link[1] = 1;
  102.     link[2] = 1;
  103.     t = idx = 2;
  104. }
  105.  
  106. void extend(int p){
  107.     while(s[p - len[t] - 1] != s[p]) t = link[t];
  108.     int x = link[t], c = s[p] - 'a';
  109.     while(s[p - len[x] - 1] != s[p]) x = link[x];
  110.     if(!tree[t][c]) {
  111.         tree[t][c] = ++idx;
  112.         occ[idx]++;
  113.         len[idx] = len[t] + 2;
  114.         link[idx] = len[idx] == 1 ? 2 : tree[x][c];
  115.     }
  116.     else occ[tree[t][c]]++;
  117.      t = tree[t][c];
  118. }
  119.  
  120. int main()
  121. {
  122.     //booster()
  123.     ///read("input.txt");
  124.  
  125.    
  126.         scanf(" %s",s+1);
  127.        
  128.         initialize();int l = strlen(s+1);
  129.         for(int i = 1;i<=l;i++){
  130.             extend(i);
  131.         }
  132.        
  133.         for(int i = idx;i>2;i--){
  134.             occ[link[i]]+=occ[i];
  135.         }
  136.         ll ans = 0;
  137.         for(int i = idx;i>2;i--)ans+=occ[i];
  138.         cout<<ans;
  139.  
  140.  
  141.  
  142.     return 0;
  143. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement