結果
問題 | No.263 Common Palindromes Extra |
ユーザー | beet |
提出日時 | 2018-11-07 13:40:16 |
言語 | C++17 (gcc 12.3.0 + boost 1.83.0) |
結果 |
AC
|
実行時間 | 314 ms / 2,000 ms |
コード長 | 2,855 bytes |
コンパイル時間 | 3,211 ms |
コンパイル使用メモリ | 228,304 KB |
実行使用メモリ | 174,192 KB |
最終ジャッジ日時 | 2024-05-07 08:07:36 |
合計ジャッジ時間 | 5,451 ms |
ジャッジサーバーID (参考情報) |
judge1 / judge2 |
(要ログイン)
テストケース
テストケース表示入力 | 結果 | 実行時間 実行使用メモリ |
---|---|---|
testcase_00 | AC | 45 ms
51,260 KB |
testcase_01 | AC | 34 ms
50,168 KB |
testcase_02 | AC | 33 ms
50,432 KB |
testcase_03 | AC | 54 ms
57,172 KB |
testcase_04 | AC | 137 ms
83,128 KB |
testcase_05 | AC | 159 ms
82,628 KB |
testcase_06 | AC | 32 ms
51,248 KB |
testcase_07 | AC | 226 ms
128,820 KB |
testcase_08 | AC | 247 ms
128,492 KB |
testcase_09 | AC | 314 ms
174,192 KB |
testcase_10 | AC | 307 ms
174,180 KB |
testcase_11 | AC | 103 ms
82,336 KB |
ソースコード
#include<bits/stdc++.h> using namespace std; using Int = long long; //BEGIN CUT HERE struct PalindromicTree{ struct node{ map<char,int> nxt; int len,suf,app,cnt; node(){} node(int len,int suf,int app,int cnt) :len(len),suf(suf),app(app),cnt(cnt){} }; vector<node> v; vector<int> ord; int n,ptr; PalindromicTree(){} PalindromicTree(const string &s) :v(s.size()+10),n(2),ptr(1){ v[0]=node(-1,0,-1,0); v[1]=node( 0,0,-1,0); for(int i=0;i<(int)s.size();i++) add_char(s,i); calc_order(); calc_count(); for(auto &x:v) x.nxt.clear(); v.resize(n); v.shrink_to_fit(); } bool add_char(const string &s,int pos){ char ch=s[pos]; int cur=ptr; 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)){ ptr=v[cur].nxt[ch]; v[ptr].cnt++; return false; } ptr=n++; v[ptr]=node(v[cur].len+2,-1,pos-v[cur].len-1,1); v[cur].nxt[ch]=ptr; if(v[ptr].len==1){ v[ptr].suf=1; return true; } while(1){ cur=v[cur].suf; if(pos-1-v[cur].len>=0&&s[pos-1-v[cur].len]==ch){ v[ptr].suf=v[cur].nxt[ch]; break; } } return true; } void calc_order(){ 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 calc_count(){ for(int i=(int)ord.size()-1;i>=0;i--) v[v[ord[i]].suf].cnt+=v[ord[i]].cnt; } }; //END CUT HERE struct RollingHash{ using ull = unsigned int; vector<ull> hash,p; RollingHash(){} RollingHash(const string &s,ull B=1777771){ int n=s.size(); hash.assign(n+1,0); p.assign(n+1,1); for(int i=0;i<n;i++){ hash[i+1]=hash[i]*B+s[i]; p[i+1]=p[i]*B; } } //s[l, r) ull find(int l,int r){ return hash[r]-hash[l]*p[r-l]; } }; //INSERT ABOVE HERE signed main(){ using ll = long long; string s,t; cin>>s>>t; PalindromicTree p1(s),p2(t); RollingHash r1(s),r2(t); using ull = RollingHash::ull; s.clear();t.clear(); 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||!m1[u.len].count(r2.find(u.app,u.app+u.len))) continue; m2[u.len][r2.find(u.app,u.app+u.len)]=u.cnt; } ll ans=0; for(int i=1;i<MAX;i++) for(auto p:m1[i]) ans+=(ll)m2[i][p.first]*p.second; cout<<ans<<endl; return 0; } /* verified on 2018/11/07 http://judge.u-aizu.ac.jp/onlinejudge/description.jsp?id=2292 https://yukicoder.me/problems/no/263 */