結果
問題 | No.263 Common Palindromes Extra |
ユーザー | beet |
提出日時 | 2018-11-07 12:58:55 |
言語 | C++17 (gcc 12.3.0 + boost 1.83.0) |
結果 |
MLE
|
実行時間 | - |
コード長 | 3,016 bytes |
コンパイル時間 | 2,894 ms |
コンパイル使用メモリ | 229,352 KB |
実行使用メモリ | 201,652 KB |
最終ジャッジ日時 | 2024-11-20 20:40:42 |
合計ジャッジ時間 | 5,741 ms |
ジャッジサーバーID (参考情報) |
judge1 / judge2 |
(要ログイン)
テストケース
テストケース表示入力 | 結果 | 実行時間 実行使用メモリ |
---|---|---|
testcase_00 | AC | 40 ms
51,128 KB |
testcase_01 | AC | 29 ms
50,296 KB |
testcase_02 | AC | 30 ms
50,460 KB |
testcase_03 | AC | 48 ms
58,020 KB |
testcase_04 | AC | 144 ms
58,192 KB |
testcase_05 | AC | 167 ms
57,432 KB |
testcase_06 | AC | 37 ms
51,536 KB |
testcase_07 | AC | 286 ms
118,320 KB |
testcase_08 | AC | 308 ms
117,932 KB |
testcase_09 | AC | 392 ms
178,148 KB |
testcase_10 | MLE | - |
testcase_11 | AC | 134 ms
57,088 KB |
ソースコード
#include<bits/stdc++.h> using namespace std; struct PalindromicTree{ struct node{ map<char,int> nxt; int len,suf,hei,app,cnt; }; vector<node> v; vector<int> ord; int n,suff; PalindromicTree(){} PalindromicTree(const string &s){init(s);build(s);} bool addchar(const string &s,int pos){ char ch=s[pos]; int cur=suff; while(1){ if(pos-1-v[cur].len>=0&&s[pos-1-v[cur].len]==ch) break; cur=v[cur].suf; } if(v[cur].nxt.count(ch)){ suff=v[cur].nxt[ch]; v[suff].cnt++; return false; } suff=n++; v[suff].len=v[cur].len+2; v[suff].app=pos-v[suff].len+1; v[suff].cnt=1; v[cur].nxt[ch]=suff; if(v[suff].len==1){ v[suff].suf=1; v[suff].hei=1; return true; } while(1){ cur=v[cur].suf; if(pos-1-v[cur].len>=0&&s[pos-1-v[cur].len]==ch){ v[suff].suf=v[cur].nxt[ch]; break; } } v[suff].hei=v[v[suff].suf].hei+1; return true; } void init(const string &s){ v.resize(s.length()+10); n=2; suff=1; v[0].app=v[1].app=-1; v[0].len=-1;v[1].len=0; v[0].suf=v[1].suf=0; v[0].hei=v[1].hei=0; } void calcOrder(){ ord.clear(); ord.push_back(0); ord.push_back(1); for(int i=0;i<(int)ord.size();i++){ for(auto &p:v[ord[i]].nxt) ord.push_back(p.second); } } void calcCount(){ assert(ord.size()); for(int i=(int)ord.size()-1;i>=0;i--){ v[v[ord[i]].suf].cnt+=v[ord[i]].cnt; } v[0].cnt=v[1].cnt=0; } void build(const string &s){ for(int i=0;i<(int)s.size();i++) addchar(s,i); calcOrder(); calcCount(); ord.clear(); for(auto &x:v) x.nxt.clear(); v.resize(n); v.shrink_to_fit(); } }; struct RollingHash{ typedef unsigned int ull; static const ull B = 1777771; vector<ull> hash; static vector<ull> p; RollingHash(){} RollingHash(const string &S){ int len=S.size(); hash.assign(len+1,0); for(int i=0;i<len;i++) hash[i+1]=hash[i]*B+S[i]; }; static void ensure(int n){ if((int)p.size()>=n) return; p.assign(n,1); for(int i=0;i+1<n;i++) p[i+1]=p[i]*B; } //S[l,r) ull find(int l,int r){ return hash[r]-hash[l]*p[r-l]; } }; vector<RollingHash::ull> RollingHash::p; using ll = long long; using ull = RollingHash::ull; signed main(){ string s,t; cin>>s>>t; PalindromicTree p1(s),p2(t); RollingHash::ensure(max(s.size()+1,t.size()+1)); RollingHash r1(s),r2(t); const int MAX = 5e5+100; map<ull, int> m1[MAX],m2[MAX]; for(int i=0;i<(int)p1.n;i++){ PalindromicTree::node& u=p1.v[i]; if(u.app<0) continue; m1[u.len][r1.find(u.app,u.app+u.len)]=u.cnt; } for(int i=0;i<(int)p2.n;i++){ PalindromicTree::node& u=p2.v[i]; if(u.app<0) continue; m2[u.len][r2.find(u.app,u.app+u.len)]=u.cnt; } ll ans=0; for(int i=1;i<=(int)s.length();i++) for(auto p:m1[i]) ans+=(ll)m2[i][p.first]*(ll)p.second; cout<<ans<<endl; return 0; }