Advertisement
jeff69

haj

Mar 14th, 2017
79
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 3.05 KB | None | 0 0
  1. #include <bits/stdc++.h>
  2. using namespace std;
  3. int n;
  4. typedef long long ll;
  5. const int MX=1e5+6,MD=1e8+7;
  6. char bb[MX];
  7. map<ll,ll> Rev,For;
  8. #define f first
  9. #define s second
  10. class Hash
  11. {
  12.     ll b,  Md,hsh,sb;
  13. public:
  14.     Hash() {}
  15.     Hash(int x,int y)
  16.     {
  17.         Md=x,b=y;
  18.         hsh=0;
  19.         sb=1;
  20.     }
  21.     ll insert(char c)
  22.     {
  23.         ll x = c - 'a' +1;
  24.  
  25.         hsh+=sb*x;
  26.         hsh%=Md;
  27.         sb*=b;
  28.         sb%=Md;
  29.         return hsh;
  30.     }
  31. };
  32. pair<ll,ll> CumHash[MX];
  33. ll dp[MX],Nigf[MX],Nigr[MX];
  34. vector<ll> Zz[MX][2];
  35. void doit(int sz,bool flag,int ij)
  36. {
  37.          Hash Make1(1e8+7,33);
  38.         Hash Make2(1e8+7,33);
  39.         for(int i=0; i<sz; i++)
  40.         {
  41.             CumHash[i+1].f     = Make1.insert(bb[i]);
  42.             CumHash[sz-i].s= Make2.insert(bb[sz-1-i]);
  43.         }
  44.         CumHash[0]=CumHash[sz+1]={0,0};
  45.         for(int i=sz+1; i<=2*sz; i++)
  46.         {
  47.             if(i%2)
  48.             {
  49.                 int s = i/2,l= sz - i/2 -1 /*Here*/, beg= i/2 + 2;
  50.                 ll hsh1 = CumHash[s].f -  CumHash[s - l].f;
  51.                 ll hsh2 =  CumHash[beg].s;
  52.                 hsh1=(hsh1+MD)%MD;
  53.                 hsh2=(hsh2+MD)%MD;
  54.                 hsh2*=dp[s-l];
  55.                 hsh2%=MD;
  56.                 if(hsh1==hsh2)
  57.                     {
  58.                     //cout<<s<<' '<<l<< ':'<<endl;
  59.                     Zz[ij][flag].push_back(CumHash[s - l].f);
  60.                     }
  61.             }
  62.             else
  63.             {
  64.                 int s = i/2,l= sz - i/2 /*Here*/, beg= i/2;
  65.                 ll hsh1 = CumHash[s].f - CumHash[s - l].f;
  66.                 ll hsh2 = CumHash[beg+1].s;
  67.                 hsh1=(hsh1+MD)%MD;
  68.                 hsh2=(hsh2+MD)%MD;
  69.                 hsh2*=dp[s-l];
  70.                 hsh2%=MD;
  71.                 if(hsh1==hsh2)
  72.                  {
  73.                   //  cout<<l<<' '<<s<<endl;
  74.                     assert(s-l==i-sz);
  75.                     Zz[ij][flag].push_back(CumHash[s-l].f);
  76.                  }
  77.             }
  78.         }
  79. }
  80. vector<int> Vv[MX];
  81. int main()
  82. {
  83.     ll ans=0,vb=1;
  84.     cin>>n;
  85.     for(int i=0; i<MX-2; i++)
  86.     {
  87.         dp[i]=vb;
  88.         vb*=33;
  89.         vb%=MD;
  90.     }
  91.     for(int ij=0; ij<n; ij++)
  92.     {
  93.         scanf("%s",bb);
  94.  
  95.         int sz=strlen(bb);
  96.         Vv[sz].push_back(ij);
  97.         doit(sz,0,ij);
  98.         Nigf[ij]=CumHash[sz].f;
  99.         //return 0;
  100.         reverse(bb,bb+sz);
  101.         doit(sz,1,ij);
  102.          Nigr[ij]=CumHash[sz].f;
  103.          /*for(auto u : Zz[ij][0])
  104.             cout<<u<<' ';
  105.          cout<<endl;*/
  106.  
  107.     }
  108.  
  109.  
  110.     for(int ix=0; ix<MX; ix++)
  111.     {
  112.         if(Vv[ix].empty())continue;
  113.        /* for(auto u : Vv[ix])
  114.         {
  115.             Rev[Nigr[u]]++;
  116.        For[Nigf[u]]++;
  117.         }*/
  118.         for(auto u : Vv[ix])
  119.         {
  120.             /*Rev[Nigr[u]]--;
  121.        For[Nigf[u]]--;*/
  122.       int i = u;
  123.      for(auto u : Zz[i][0])
  124.             ans+=Rev[u];
  125.      for(auto u : Zz[i][1])
  126.             ans+=For[u];
  127.        Rev[Nigr[i]]++;
  128.        For[Nigf[i]]++;
  129.         }
  130.     }
  131.     cout<<ans;
  132.     return 0;
  133. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement