Submission #1168524

#TimeUsernameProblemLanguageResultExecution timeMemory
1168524_rain_Selling RNA Strands (JOI16_selling_rna)C++20
100 / 100
144 ms66376 KiB
#include<bits/stdc++.h> using namespace std; typedef long long LL; const int N=(int)2e5; const int MAXLOG=18; pair<string,int> s[N+2]; string q[N+2]; int num=0; int n,m; int lcp[2*N+2][MAXLOG+2],LOG[N*2+2]; bool cmp(pair<string,int>&x1,pair<string,int>&x2){ if (x1.first!=x2.first) return x1<x2; return x1.second<x2.second; } LL ans[N+2]; int Getmn(int l,int r){ if (l>r) return 0; int x=LOG[r-l+1]; return min(lcp[l][x],lcp[r-(1<<x)+1][x]); } struct Node{ int child[4]={}; int cnt=0; Node(){ memset(child,-1,sizeof child); cnt=0; } }; int type(char x){ if (x=='G') return 0; if (x=='U') return 1; if (x=='A') return 2; if (x=='C') return 3; } class Trie{ public: vector<Node>v; void init(){ v.push_back(Node()); } void add(string &x,int addmore){ int root=0; for(int i=0;i<x.size();++i){ int c=type(x[i]); if (v[root].child[c]==-1) v[root].child[c]=v.size(),v.push_back(Node()); v[root].cnt+=addmore; root=v[root].child[c]; } v[root].cnt+=addmore; } int Find(string&x){ int root=0; for(int i=0;i<x.size();++i){ int c=type(x[i]); if (v[root].child[c]==-1) return 0; root=v[root].child[c]; } return v[root].cnt; } }; Trie tree; int Getlcp(int l,int r){ if (l>r) swap(l,r); return Getmn(l+1,r); } const int BLOCKSIZE=447; struct Mo_dtcl{ int l,r,id; bool operator <(const Mo_dtcl&other) const{ if (l/BLOCKSIZE!=other.l/BLOCKSIZE){ return l/BLOCKSIZE<other.l/BLOCKSIZE; } return r<other.r; } }; vector<Mo_dtcl> qs; int Lower(int id,int need){ int l=1,r=id-1,pos=id; while (l<=r){ int m=(l+r)/2; if (Getlcp(m,id)!=need) l=m+1; else { pos=m; r=m-1; } } return pos; } int Upper(int id,int need){ int l=id+1,r=num,pos=id; while (l<=r){ int m=(l+r)/2; if (Getlcp(id,m)!=need) r=m-1; else { pos=m; l=m+1; } } return pos; } void cong(int id,int val){ if (s[id].second==0) tree.add(s[id].first,val); } int main(){ ios::sync_with_stdio(false); cin.tie(0) ; cout.tie(0); cin>>n>>m; for(int i=1;i<=n;++i){ string t; cin>>t; s[++num]={t,0}; } for(int i=1;i<=m;++i){ string t; cin>>t; cin>>q[i]; reverse(q[i].begin(),q[i].end()); s[++num]={t,i}; } sort(s+1,s+num+1,cmp); lcp[1][0]=s[1].first.size(); for(int i=2;i<=num;++i){ for(int j=0;j<min(s[i-1].first.size(),s[i].first.size());++j){ if (s[i-1].first[j]!=s[i].first[j]) break; lcp[i][0]++; } } for(int i=2;i<=num;++i) LOG[i]=LOG[i/2]+1; for(int j=1;j<=MAXLOG;++j){ for(int i=1;i+(1<<j)-1<=num;++i) { lcp[i][j]=min(lcp[i][j-1],lcp[i+(1<<(j-1))][j-1]); } } for(int i=1;i<=num;++i) reverse(s[i].first.begin(),s[i].first.end()); tree.init(); for(int i=1;i<=num;++i){ if (s[i].second!=0){ int l=Lower(i,s[i].first.size()); int r=Upper(i,s[i].first.size()); qs.push_back({l,r,s[i].second}); } } sort(qs.begin(),qs.end()); int l=1,r=0; for(auto&x:qs){ while (l<x.l) cong(l++,-1); while (l>x.l) cong(--l,1); while (r<x.r) cong(++r,1); while (r>x.r) cong(r--,-1); ans[x.id]=tree.Find(q[x.id]); } for(int i=1;i<=m;++i) cout<<ans[i]<<'\n'; }

Compilation message (stderr)

selling_rna.cpp: In function 'int type(char)':
selling_rna.cpp:38:1: warning: control reaches end of non-void function [-Wreturn-type]
   38 | }
      | ^
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...