Submission #291891

#TimeUsernameProblemLanguageResultExecution timeMemory
291891eggag32Selling RNA Strands (JOI16_selling_rna)C++17
0 / 100
1606 ms102400 KiB
#pragma GCC optimize ("O3") #pragma GCC target ("sse4") #include <bits/stdc++.h> using namespace std; typedef long long ll; typedef long double ld; typedef vector<int> vi; typedef pair<int, int> pi; #define debug(x) cerr << #x << ": " << x << endl #define debug2(x, y) debug(x), debug(y) #define repn(i, a, b) for(int i = (int)(a); i < (int)(b); i++) #define rep(i, a) for(int i = 0; i < (int)(a); i++) #define all(v) v.begin(), v.end() #define mp make_pair #define pb push_back #define lb lower_bound #define ub upper_bound #define fi first #define se second #define sq(x) ((x) * (x)) const int mxN = 1e5 + 5; const int MOD = 1e9 + 7; const int MOD2 = 1e9 + 9; template<class T> T gcd(T a, T b){ return ((b == 0) ? a : gcd(b, a % b)); } int n, m; string s[mxN]; pair<pair<string, string>, int> p[mxN]; multiset<pair<ll, ll>> hshs; pair<ll, ll> h[mxN]; bool cmp(pair<pair<string, string>, int> a, pair<pair<string, string>, int> b){ return a.fi.fi < b.fi.fi; } void add(int ind){ //deletes all the suffix hashes of s[ind] ll hsh = 1LL, hsh1 = 1LL; string s1 = s[ind]; reverse(all(s1)); for(int j = 1; j <= (int)s1.size(); j++){ hsh = (hsh * 179) + (ll)(s1[j - 1] - 'a') + 1; hsh1 = (hsh1 * 131) + (ll)(s1[j - 1] - 'a') + 1; hsh %= MOD; hsh1 %= MOD2; hshs.insert(mp(hsh, hsh1)); } } void del(int ind){ //adds all the suffix hashes of s[ind] ll hsh = 1LL, hsh1 = 1LL; string s1 = s[ind]; reverse(all(s1)); for(int j = 1; j <= (int)s1.size(); j++){ hsh = (hsh * 179) + (ll)(s1[j - 1] - 'a') + 1; hsh1 = (hsh1 * 131) + (ll)(s1[j - 1] - 'a') + 1; hsh %= MOD; hsh1 %= MOD2; auto it = hshs.find(mp(hsh, hsh1)); if(it != hshs.end()) hshs.erase(it); } } int main(){ ios_base::sync_with_stdio(false); cin.tie(0); //freopen("input.in", "r", stdin); //freopen("output.out", "w", stdout); cin >> n >> m; rep(i, n) cin >> s[i]; sort(s, s + n); rep(i, m){ cin >> p[i].fi.fi >> p[i].fi.se; p[i].se = i; } sort(p, p + m, cmp); rep(i, m){ string nw = p[i].fi.se; reverse(all(nw)); ll hsh = 1LL, hsh1 = 1LL; for(int j = 1; j <= (int)nw.size(); j++){ hsh = (hsh * 179) + (ll)(nw[j - 1] - 'a') + 1; hsh1 = (hsh1 * 131) + (ll)(nw[j - 1] - 'a') + 1; hsh %= MOD; hsh1 %= MOD2; } h[i] = mp(hsh, hsh1); } vi ext(n, 0), ans(m, 0); repn(i, 1, n){ if(s[i].size() > s[i - 1].size()){ int f = 1; rep(j, s[i - 1].size()){ if(s[i][j] != s[i - 1][j]){ f = 0; break; } } ext[i] = f; } } int l = 1e9, r = 0; rep(i, m){ if(ext[i]){ //we would always narrow the [l, r] range if(l == 1e9){ ans[p[i].se] = 0; continue; } //modify the range vi vis(n, 0); repn(j, l, r + 1){ if(s[j].size() < p[i].fi.fi.size()){ del(j); l++; vis[j] = 1; continue; } string nw = s[j].substr(0, p[i].fi.fi.size()); if(nw != p[i].fi.fi) break; del(j); l++; vis[j] = 1; } for(int j = r; j >= l; j--){ if(vis[j]) break; if(s[j].size() < p[i].fi.fi.size()){ del(j); r--; continue; } string nw = s[j].substr(0, p[i].fi.fi.size()); if(nw != p[i].fi.fi) break; del(j); r--; } if(l > r) l = 1e9; } else{ l = 1e9, r = 0; hshs.clear(); int lo = 0, hi = n - 1; while(lo < hi){ int mid = (lo + hi + 1) / 2; if(s[mid] < p[i].fi.fi) lo = mid; else hi = mid - 1; } if(lo == 0 && s[lo] >= p[i].fi.fi) lo = -1; repn(j, lo + 1, n){ if(s[j].size() < p[i].fi.fi.size()) break; string nw = s[j].substr(0, p[i].fi.fi.size()); if(nw != p[i].fi.fi) break; add(j); l = min(l, j), r = max(r, j); } } ans[p[i].se] = hshs.count(h[i]); } rep(i, m) cout << ans[i] << '\n'; return 0; } /* Things to look out for: - Integer overflows - Array bounds - Special cases Be careful! */
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...