Submission #1312966

#TimeUsernameProblemLanguageResultExecution timeMemory
1312966Zbyszek99Selling RNA Strands (JOI16_selling_rna)C++20
35 / 100
1597 ms47608 KiB
#include <bits/stdc++.h> #include <ext/pb_ds/assoc_container.hpp> #include <ext/pb_ds/tree_policy.hpp> #define ll long long #define ld long double #define ull unsigned long long #define ff first #define ss second #define pii pair<int,int> #define pll pair<long long, long long> #define vi vector<int> #define vl vector<long long> #define pb push_back #define rep(i, b) for(int i = 0; i < (b); ++i) #define rep2(i,a,b) for(int i = a; i <= (b); ++i) #define rep3(i,a,b,c) for(int i = a; i <= (b); i+=c) #define count_bits(x) __builtin_popcountll((x)) #define all(x) (x).begin(),(x).end() #define siz(x) (int)(x).size() #define forall(it,x) for(auto& it:(x)) using namespace __gnu_pbds; using namespace std; typedef tree<int, null_type, less<int>, rb_tree_tag,tree_order_statistics_node_update> ordered_set; //mt19937 mt;void random_start(){mt.seed(chrono::time_point_cast<chrono::milliseconds>(chrono::high_resolution_clock::now()).time_since_epoch().count());} //ll los(ll a, ll b) {return a + (mt() % (b-a+1));} const int INF = 1e9+50; const ll INF_L = 1e18+40; const ll MOD = 1e9+7; struct suf_str; ll p[2] = {2137,692137}; ll P[2][100001]; vector<string> str; vector<vector<pll>> suf_hash; unordered_map<ll,int> ans_map; vector<suf_str> ans_map2[100002]; struct suf_str { int ind; int get_lcp(suf_str other) const { int l = 0; int r = min(siz(str[ind])-1,siz(str[other.ind])-1); int ans = -1; while(l <= r) { int mid = (l+r)/2; if(suf_hash[ind][mid].ff == suf_hash[other.ind][mid].ff && suf_hash[ind][mid].ss == suf_hash[other.ind][mid].ss) { ans = mid; l = mid+1; } else { r = mid-1; } } return ans; } bool operator<(const suf_str& other) const { int ans = get_lcp(other); if(ans == siz(str[other.ind])-1) return 0; if(ans == siz(str[ind])-1) return 1; return str[ind][siz(str[ind])-ans-2] < str[other.ind][siz(str[other.ind])-ans-2]; } }; void add_string(string s) { str.pb(s); suf_hash.pb({}); suf_hash.back().resize(siz(s)); ll h[2]; h[0] = 0; h[1] = 0; for(int j = siz(s)-1; j >= 0; j--) { rep(d,2) h[d] = (h[d]+P[d][siz(s)-1-j]*s[j])%MOD; suf_hash.back()[siz(s)-1-j] = {h[0],h[1]}; } } int main() { ios_base::sync_with_stdio(0);cin.tie(0);//cerr.tie(0); //random_start(); rep(d,2) { P[d][0] = 1; rep2(i,1,100000) P[d][i] = (P[d][i-1]*p[d])%MOD; } int n,q; cin >> n >> q; int cur = 1; rep(i,n) { string s; cin >> s; add_string(s); ll h[2]; h[0] = 0; h[1] = 0; rep(j,siz(s)) { rep(d,2) h[d] = (h[d]+P[d][j]*s[j])%MOD; if(ans_map.find(h[0]+h[1]*MOD) == ans_map.end()) ans_map[h[0]+h[1]*MOD] = cur++; ans_map2[ans_map[h[0]+h[1]*MOD]].pb({i}); } } rep2(i,1,cur-1) sort(all(ans_map2[i])); rep(qq,q) { string s1,s2; cin >> s1 >> s2; ll h[2]; h[0] = 0; h[1] = 0; rep(i,siz(s1)) rep(d,2) h[d] = (h[d]+P[d][i]*s1[i])%MOD; ll p = ans_map[h[0]+h[1]*MOD]; if(p == 0) { continue; } add_string(s2); suf_str s2_ = {siz(str)-1}; int l = 0; int r = siz(ans_map2[p])-1; int l_ans = siz(ans_map2[p]); while(l <= r) { int mid = (l+r)/2; if(!(ans_map2[p][mid] < s2_)) { l_ans = mid; r = mid-1; } else { l = mid+1; } } l = l_ans; r = siz(ans_map2[p])-1; int r_ans = -1; while(l <= r) { int mid = (l+r)/2; if(ans_map2[p][mid].get_lcp(s2_) == siz(s2)-1) { r_ans = mid; l = mid+1; } else { r = mid-1; } } cout << max(0,r_ans-l_ans+1) << "\n"; } }
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...