Submission #64454

#TimeUsernameProblemLanguageResultExecution timeMemory
64454realitySelling RNA Strands (JOI16_selling_rna)C++17
35 / 100
1579 ms319820 KiB
#include "bits/stdc++.h" using namespace std; #define fi first #define se second #define ll long long #define dbg(v) cerr<<#v<<" = "<<v<<'\n' #define vi vector<int> #define vl vector <ll> #define pii pair<int,int> #define mp make_pair #define db long double #define pb push_back #define all(s) s.begin(),s.end() template < class T > ostream& operator<<(ostream& stream, const vector<T> v){ stream << "[ "; for (int i=0; i<(int)v.size(); i++) stream << v[i] << " "; stream << "]"; return stream;} template < class T > T smin(T &a,T b) {if (a > b) a = b;return a;} template < class T > T smax(T &a,T b) {if (a < b) a = b;return a;} struct trie { trie * t[4]; vi p; trie(void) { memset(t,0,sizeof(t)); } }; const int mod1 = 1e9 + 7; const int mod2 = 1e9 + 9; const int base = 5; struct md { int x,y; md(void) { x = y = 0; } md(int c) { x = y = c; } md(int xx,int yy) { x = xx; y = yy; } }; bool operator == (md a,md b) { return a.x == b.x && a.y == b.y; } inline int sm1(int x,int y) {x += y;if (x >= mod1) x -= mod1;return x;} inline int sm2(int x,int y) {x += y;if (x >= mod2) x -= mod2;return x;} md operator + (md a,md b) { return md(sm1(a.x,b.x),sm2(a.y,b.y)); } md operator * (md a,md b) { return md((1ll * a.x * b.x) % mod1,(1ll * a.y * b.y) % mod2); } typedef trie * tr; const int N = 2e5 + 5; const int LG = 18; string s[N]; int Log[N]; vector < md > h[N][LG + 1]; md H[LG + 1][N]; md pw[N]; tr root = new trie(); void dfs(tr rt,int dep = -1) { if (!rt) return; sort(all(rt->p),[&](int a,int b) { int sz1 = s[a].length(); int sz2 = s[b].length(); for (int t = Log[min(sz1,sz2)];t >= 0;--t) if (sz1 - (1 << t) >= 0 && sz2 - (1 << t) >= 0 && h[a][t][sz1 - (1 << t)] == h[b][t][sz2 - (1 << t)]) sz1 -= (1 << t),sz2 -= (1 << t); --sz1;--sz2; if (sz1 < 0 || sz2 < 0) return sz1 < sz2; return s[a][sz1] < s[b][sz2]; }); for (int i = 0;i < 4;++i) dfs(rt->t[i],dep + 1); } int main(void) { int n,m; cin>>n>>m; pw[0] = md(1,1); for (int i = 1;i <= 1e5 + 5;++i) pw[i] = pw[i - 1] * md(base,base); for (int i = 2;i <= 1e5 + 5;++i) Log[i] = Log[i / 2] + 1; for (int i = 1;i <= n;++i) { cin>>s[i]; for (auto & it : s[i]) { if (it == 'A') it = 1; else if (it == 'G') it = 2; else if (it == 'C') it = 3; else it = 4; } tr cnt = root; int sz = s[i].length(); for (int j = 0;j < sz;++j) { int ch = s[i][j] - 1; if (!cnt->t[ch]) cnt->t[ch] = new trie(); cnt = cnt->t[ch]; cnt->p.pb(i); } for (int k = 0;sz >> k;++k) { h[i][k].resize(sz); } for (int j = 0;j < sz;++j) h[i][0][j] = md(s[i][j],s[i][j]); for (int k = 1;sz >> k;++k) for (int j = 0;j + (1 << k) <= sz;++j) h[i][k][j] = h[i][k - 1][j] + pw[1 << (k - 1)] * h[i][k - 1][j + (1 << (k - 1))]; } dfs(root); while (m --) { string a,b; cin>>a>>b; tr cnt = root; for (auto &it : a) { if (it == 'A') it = 1; else if (it == 'G') it = 2; else if (it == 'C') it = 3; else it = 4; } for (auto &it : b) { if (it == 'A') it = 1; else if (it == 'G') it = 2; else if (it == 'C') it = 3; else it = 4; } for (auto it : a) { int ch = it - 1; cnt = cnt->t[ch]; if (!cnt) break; } if (!cnt) { cout << "0\n"; continue; } int sz = b.length(); for (int i = 0;i < sz;++i) H[0][i] = md(b[i]); for (int k = 1;sz >> k;++k) for (int i = 0;i + (1 << k) <= sz;++i) H[k][i] = H[k - 1][i] + pw[1 << (k - 1)] * H[k - 1][i + (1 << (k - 1))]; int SZ = cnt->p.size(); auto ls = [&](int index) { assert(0 <= index && index < SZ); index = cnt->p[index]; int sz1 = s[index].length(); int sz2 = sz; for (int t = Log[min(sz1,sz2)];t >= 0;--t) if (sz1 - (1 << t) >= 0 && sz2 - (1 << t) >= 0 && H[t][sz2 - (1 << t)] == h[index][t][sz1 - (1 << t)]) sz1 -= 1 << t,sz2 -= 1 << t; --sz1;--sz2; if (sz1 < 0 || sz2 < 0) return sz2 > sz1; return b[sz2] > s[index][sz1]; }; auto eq = [&](int index) { assert(0 <= index && index < SZ); index = cnt->p[index]; int sz1 = s[index].length(); int sz2 = sz; for (int t = Log[min(sz1,sz2)];t >= 0;--t) if (sz1 - (1 << t) >= 0 && sz2 - (1 << t) >= 0 && H[t][sz2 - (1 << t)] == h[index][t][sz1 - (1 << t)]) sz1 -= 1 << t,sz2 -= 1 << t; return !sz2; }; int l = -1; for (int t = Log[SZ];t >= 0;--t) if (l + (1 << t) < SZ && ls(l + (1 << t))) l += (1 << t); int r = ++l; for (int t = Log[SZ];t >= 0;--t) if (r + (1 << t) <= SZ && eq(r + (1 << t) - 1)) r += 1 << t; cout << (r - l) << '\n'; } return 0; }
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...