Submission #60270

#TimeUsernameProblemLanguageResultExecution timeMemory
60270BenqSelling RNA Strands (JOI16_selling_rna)C++11
100 / 100
393 ms154496 KiB
#include <bits/stdc++.h> #include <ext/pb_ds/tree_policy.hpp> #include <ext/pb_ds/assoc_container.hpp> using namespace std; using namespace __gnu_pbds; typedef long long ll; typedef long double ld; typedef complex<ld> cd; typedef pair<int, int> pi; typedef pair<ll,ll> pl; typedef pair<ld,ld> pd; typedef vector<int> vi; typedef vector<ld> vd; typedef vector<ll> vl; typedef vector<pi> vpi; typedef vector<pl> vpl; typedef vector<cd> vcd; template <class T> using Tree = tree<T, null_type, less<T>, rb_tree_tag,tree_order_statistics_node_update>; #define FOR(i, a, b) for (int i=a; i<(b); i++) #define F0R(i, a) for (int i=0; i<(a); i++) #define FORd(i,a,b) for (int i = (b)-1; i >= a; i--) #define F0Rd(i,a) for (int i = (a)-1; i >= 0; i--) #define sz(x) (int)(x).size() #define mp make_pair #define pb push_back #define f first #define s second #define lb lower_bound #define ub upper_bound #define all(x) x.begin(), x.end() const int MOD = 1000000007; const ll INF = 1e18; const int MX = 100001; int cat(char c) { switch(c) { case 'A': return 0; case 'C': return 1; case 'G': return 2; default: return 3; } } template<int MX> struct tri { int trie[MX][4], nex = 0; // easily changed to character int sz[MX], EN[MX]; tri() { memset(trie,0,sizeof trie); } void ins(string t) { // insert or delete int cur = 0; sz[cur] ++; for (char c: t) { int C = cat(c); if (!trie[cur][C]) { trie[cur][C] = ++nex; // if U } cur = trie[cur][C]; sz[cur] ++; } EN[cur] ++; } pi getBound(string t) { int cur = 0, st = 0; for (char c: t) { int C = cat(c); if (!trie[cur][C]) return {0,-1}; F0R(i,C) if (trie[cur][i]) { // cout << "OOPS " << sz(t) << " " << cur << " " << i << " " << trie[cur][i] << "\n"; st += sz[trie[cur][i]]; } st += EN[cur]; // cout << "HUH " << cur << " " << EN[cur] << "\n"; cur = trie[cur][C]; } return {st+1,st+sz[cur]}; } }; tri<2000001> t0, t1; template<class T, int SZ> struct BIT { T bit[SZ+1]; BIT() { memset(bit,0,sizeof bit); } void upd(int k, T val) { // add val to index k for( ;k <= SZ; k += (k&-k)) bit[k] += val; } T query(int k) { T temp = 0; for (;k > 0;k -= (k&-k)) temp += bit[k]; return temp; } T query(int l, int r) { return query(r)-query(l-1); } // range query [l,r] }; BIT<int,MX> B; int N,M, ans[MX], beg[MX], en[MX]; vector<pair<string,int>> v0, v1; vector<array<int,3>> v[MX]; vi ad[MX]; void input() { ios_base::sync_with_stdio(0); cin.tie(0); cin >> N >> M; FOR(i,1,N+1) { string s; cin >> s; t0.ins(s); v0.pb({s,i}); reverse(all(s)); t1.ins(s); v1.pb({s,i}); } sort(all(v0)), sort(all(v1)); F0R(i,N) { // cout << v0[i].f << " " << t0.getBound(v0[i].f).f << " " << t0.getBound(v0[i].f).s << "\n"; beg[v0[i].s] = i+1; en[v1[i].s] = i+1; } FOR(i,1,N+1) { ad[beg[i]].pb(en[i]); // cout << beg[i] << " " << en[i] << "\n"; } } int main() { input(); F0R(i,M) { string P, Q; cin >> P >> Q; reverse(all(Q)); pi x = t0.getBound(P), y = t1.getBound(Q); // cout << x.f << " " << x.s << " " << y.f << " " << y.s << "\n"; if (x.f > x.s || y.f > y.s) continue; v[x.f-1].pb({y.s,-1,i}); v[x.f-1].pb({y.f-1,1,i}); v[x.s].pb({y.s,1,i}); v[x.s].pb({y.f-1,-1,i}); } FOR(i,1,N+1) { for (int y: ad[i]) B.upd(y,1); for (auto a: v[i]) ans[a[2]] += a[1]*B.query(a[0]); } F0R(i,M) cout << ans[i] << "\n"; } /* Look for: * the exact constraints (multiple sets are too slow for n=10^6 :( ) * special cases (n=1?) * overflow (ll vs int?) * array bounds */
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...