日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

Codeforces 666E. Forensic Examination

發布時間:2023/12/2 编程问答 35 豆豆
生活随笔 收集整理的這篇文章主要介紹了 Codeforces 666E. Forensic Examination 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

Description

給出串 \(S\) ,和 \(m\) 個串 \(T_i\) ,每次詢問 \((l,r,pl,pr)\) 表示 \(S[pl...pr]\)\(T[l...r]\) 中哪一個出現次數最多,求出現次數和編號
題面

Solution

基礎題...
對于 \(S,T[l...r]\) 放在一起建廣義后綴自動機
然后每次倍增到 S[pl,pr] ,然后查詢子樹內出現次數最多的 \(T\) 即可
我們可以開一棵 \([1,m]\) 的線段樹,維護每一個 \(T\) 的出現次數,維護最大值和最大值位置
線段樹合并上來就好了

#include<bits/stdc++.h> using namespace std; template<class T>void gi(T &x){int f;char c;for(f=1,c=getchar();c<'0'||c>'9';c=getchar())if(c=='-')f=-1;for(x=0;c<='9'&&c>='0';c=getchar())x=x*10+(c&15);x*=f; } const int N=1100010; int n,m,Q,ch[N][26],cur=1,cnt=1,len[N],fa[N],pos[N],rt[N];char s[N]; int head[N],nxt[N],to[N],num=0,pa[N][20],tt=0,ls[N*20],rs[N*20]; inline void link(int x,int y){nxt[++num]=head[x];to[num]=y;head[x]=num;} inline void ins(int c){int p=cur;cur=++cnt;len[cur]=len[p]+1;for(;p && !ch[p][c];p=fa[p])ch[p][c]=cur;if(!p)fa[cur]=1;else{int q=ch[p][c];if(len[p]+1==len[q])fa[cur]=q;else{int nt=++cnt;len[nt]=len[p]+1;memcpy(ch[nt],ch[q],sizeof(ch[nt]));fa[nt]=fa[q];fa[cur]=fa[q]=nt;for(;p && ch[p][c]==q;p=fa[p])ch[p][c]=nt;}} } struct data{int w,p;}tr[N*20]; inline data upd(data x,data y){if(x.w>=y.w)return x;return y; } inline int merge(int x,int y){if(!x||!y)return x+y;int o=++tt;if(!ls[x] && !rs[x]){tr[o].w=tr[x].w+tr[y].w;tr[o].p=tr[x].p;return o;}ls[o]=merge(ls[x],ls[y]);rs[o]=merge(rs[x],rs[y]);tr[o]=upd(tr[ls[o]],tr[rs[o]]);return o; } inline void mdf(int &x,int l,int r,int sa){if(!x)x=++tt;if(l==r){tr[x].w++;tr[x].p=l;return ;}int mid=(l+r)>>1;if(sa<=mid)mdf(ls[x],l,mid,sa);else mdf(rs[x],mid+1,r,sa);tr[x]=upd(tr[ls[x]],tr[rs[x]]); } inline void dfs(int x){for(int i=1;i<=19;i++)pa[x][i]=pa[pa[x][i-1]][i-1];for(int i=head[x];i;i=nxt[i])dfs(to[i]),rt[x]=merge(rt[x],rt[to[i]]); } inline int lca(int x,int k){for(int i=19;i>=0;i--)if(len[pa[x][i]]>=k)x=pa[x][i];return x; } inline data qry(int x,int l,int r,int sa,int se){if(sa<=l && r<=se)return tr[x];int mid=(l+r)>>1;if(se<=mid)return qry(ls[x],l,mid,sa,se);if(sa>mid)return qry(rs[x],mid+1,r,sa,se);return upd(qry(ls[x],l,mid,sa,mid),qry(rs[x],mid+1,r,mid+1,se)); } int main(){freopen("pp.in","r",stdin);freopen("pp.out","w",stdout);scanf("%s",s+1);n=strlen(s+1);for(int i=1;i<=n;i++)ins(s[i]-'a'),pos[i]=cur;cin>>m;for(int i=1;i<=m;i++){scanf("%s",s+1);cur=1;for(int j=1,len=strlen(s+1);j<=len;j++)ins(s[j]-'a'),mdf(rt[cur],1,m,i);}for(int i=2;i<=cnt;i++)link(fa[i],i),pa[i][0]=fa[i];dfs(1);int x,y,l,r;cin>>Q;while(Q--){gi(l);gi(r);gi(x);gi(y);x=lca(pos[y],y-x+1);data t=qry(rt[x],1,m,l,r);if(t.w)printf("%d %d\n",t.p,t.w);else printf("%d 0\n",l);}return 0; }

轉載于:https://www.cnblogs.com/Yuzao/p/9098887.html

總結

以上是生活随笔為你收集整理的Codeforces 666E. Forensic Examination的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。