結果
問題 | No.263 Common Palindromes Extra |
ユーザー | beet |
提出日時 | 2019-10-29 14:55:00 |
言語 | C++17 (gcc 12.3.0 + boost 1.83.0) |
結果 |
AC
|
実行時間 | 253 ms / 2,000 ms |
コード長 | 3,697 bytes |
コンパイル時間 | 2,765 ms |
コンパイル使用メモリ | 227,548 KB |
実行使用メモリ | 187,800 KB |
最終ジャッジ日時 | 2024-09-14 21:29:23 |
合計ジャッジ時間 | 4,790 ms |
ジャッジサーバーID (参考情報) |
judge6 / judge4 |
(要ログイン)
テストケース
テストケース表示入力 | 結果 | 実行時間 実行使用メモリ |
---|---|---|
testcase_00 | AC | 22 ms
33,432 KB |
testcase_01 | AC | 10 ms
26,880 KB |
testcase_02 | AC | 11 ms
27,136 KB |
testcase_03 | AC | 33 ms
43,488 KB |
testcase_04 | AC | 109 ms
110,196 KB |
testcase_05 | AC | 127 ms
110,012 KB |
testcase_06 | AC | 22 ms
35,304 KB |
testcase_07 | AC | 203 ms
147,356 KB |
testcase_08 | AC | 210 ms
147,000 KB |
testcase_09 | AC | 253 ms
187,800 KB |
testcase_10 | AC | 252 ms
187,800 KB |
testcase_11 | AC | 94 ms
109,744 KB |
ソースコード
#ifndef call_from_test #include<bits/stdc++.h> using namespace std; using Int = long long; #endif //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> vs; vector<int> ord; int n,ptr; PalindromicTree(){} PalindromicTree(const string &s) :vs(s.size()+10),n(2),ptr(1){ vs[0]=node(-1,0,-1,0); vs[1]=node( 0,0,-1,0); for(int i=0;i<(int)s.size();i++) add_char(s,i); calc_order(); calc_count(); } bool add_char(const string &s,int pos){ char ch=s[pos]; int cur=ptr; while(1){ int rev=pos-1-vs[cur].len; if(rev>=0&&s[rev]==ch) break; cur=vs[cur].suf; } if(vs[cur].nxt.count(ch)){ ptr=vs[cur].nxt[ch]; vs[ptr].cnt++; return false; } ptr=n++; vs[ptr]=node(vs[cur].len+2,-1,pos-vs[cur].len-1,1); vs[cur].nxt[ch]=ptr; if(vs[ptr].len==1){ vs[ptr].suf=1; return true; } while(1){ cur=vs[cur].suf; int rev=pos-1-vs[cur].len; if(rev>=0&&s[rev]==ch){ vs[ptr].suf=vs[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:vs[ord[i]].nxt) ord.push_back(p.second); } void calc_count(){ for(int i=(int)ord.size()-1;i>=0;i--) vs[vs[ord[i]].suf].cnt+=vs[ord[i]].cnt; } }; //END CUT HERE #ifndef call_from_test #define call_from_test #ifndef call_from_test #include<bits/stdc++.h> using namespace std; using Int = long long; #endif //BEGIN CUT HERE struct FastIO{ FastIO(){ cin.tie(0); ios::sync_with_stdio(0); } }fastio_beet; //END CUT HERE #ifndef call_from_test signed main(){ return 0; } #endif #ifndef call_from_test #include<bits/stdc++.h> using namespace std; #endif //BEGIN CUT HERE template<typename T,T MOD,T B> struct RollingHash{ using ll = long long; vector<T> hash,po; RollingHash(){} RollingHash(vector<T> vs){init(vs);} RollingHash(string &s){ vector<T> vs; for(char c:s) vs.emplace_back(c); init(vs); } void init(vector<T> vs){ int n=vs.size(); hash.assign(n+1,0); po.assign(n+1,1); for(int i=0;i<n;i++){ hash[i+1]=((ll)hash[i]*B+vs[i])%MOD; po[i+1]=(ll)po[i]*B%MOD; } } //S[l, r) T find(int l,int r){ T res=(ll)hash[r]+MOD-(ll)hash[l]*po[r-l]%MOD; return res>=MOD?res-MOD:res; } }; //END CUT HERE #ifndef call_from_test //INSERT ABOVE HERE signed main(){ return 0; } #endif #undef call_from_test //INSERT ABOVE HERE signed YUKI_263(){ using ll = long long; string s,t; cin>>s>>t; PalindromicTree p1(s),p2(t); const int MOD = 1e9+7; const int BASE1 = 1777771; const int BASE2 = 1e6+3; RollingHash<int, MOD, BASE1> rs1(s),rt1(t); RollingHash<int, MOD, BASE2> rs2(s),rt2(t); const int MAX = 5e5+100; map<pair<int, int>, int> m1[MAX]; for(int i=0;i<(int)p1.n;i++){ PalindromicTree::node& u=p1.vs[i]; if(u.app<0) continue; auto p=make_pair(rs1.find(u.app,u.app+u.len), rs2.find(u.app,u.app+u.len)); m1[u.len][p]=u.cnt; } ll ans=0; for(int i=0;i<(int)p2.n;i++){ PalindromicTree::node& u=p2.vs[i]; auto p=make_pair(rt1.find(u.app,u.app+u.len), rt2.find(u.app,u.app+u.len)); if(u.app<0||!m1[u.len].count(p)) continue; ans+=(ll)m1[u.len][p]*u.cnt; } cout<<ans<<endl; return 0; } /* verified on 2019/10/29 https://yukicoder.me/problems/no/263 */ signed main(){ YUKI_263(); return 0; } #endif