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

歡迎訪問(wèn) 生活随笔!

生活随笔

當(dāng)前位置: 首頁(yè) > 编程资源 > 编程问答 >内容正文

编程问答

[BJWC2018]Border 的四种求法(后缀自动机+链分治+线段树合并)

發(fā)布時(shí)間:2025/6/15 编程问答 27 豆豆
生活随笔 收集整理的這篇文章主要介紹了 [BJWC2018]Border 的四种求法(后缀自动机+链分治+线段树合并) 小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

題目描述

給一個(gè)小寫字母字符串 S ,q 次詢問(wèn)每次給出 l,r ,求 s[l..r] 的 Border 。

Border: 對(duì)于給定的串 s ,最大的 i 使得 s[1..i] = s[|s|-i+1..|s|], |s| 為 s 的長(zhǎng)度。

題解

這題的描述很短,給人一種很可做的假象。

暴力1:每次對(duì)區(qū)間lr做一次KMP,求出border數(shù)組,復(fù)雜度nq。

暴力2:構(gòu)建后綴自動(dòng)機(jī),用線段樹(shù)合并維護(hù)出right集合考慮到兩個(gè)串的最長(zhǎng)后綴為他們?cè)趐arent樹(shù)上的LCA的len,所以我們可以在parent樹(shù)上跳father,相當(dāng)于枚舉LCA,那么如果有匹配的點(diǎn),則一定滿足:

i-len[LCA]+1<=l => i=len[LCA]<l => i<l+len[LCA]? ? ? ?i>=l&&i<r (i為我們要求的點(diǎn),l為詢問(wèn)的左端點(diǎn),LCA為i和r的LCA)

所以我們只需要在線段樹(shù)上查子樹(shù)內(nèi)查詢滿足上述條件的最大的i就可以了,復(fù)雜度最好qlogn,最差qn。

這兩種暴力好像差不多。。

我們觀察到第二種暴力它的瓶頸在于枚舉LCA,但查詢只需要一個(gè)log,我們可以想一些辦法把復(fù)雜度均攤一下。

鏈分治

這就是這道題的重頭戲,它用到了一個(gè)重要的性質(zhì),我們將一棵樹(shù)重鏈剖分之后,從根到任意一點(diǎn)的路徑上,輕重鏈切換的次數(shù)是不超過(guò)log的。

然后我們就可以用它搞一些事情。

比如說(shuō)這道題,我們可以把詢問(wèn)拆成log個(gè)掛在它到根的路徑上,每條鏈掛一個(gè),對(duì)于當(dāng)前鏈,掛在原來(lái)的點(diǎn)上,對(duì)于上面的鏈,掛在鏈的最底端。

其實(shí)我們也是相當(dāng)于在枚舉lca,對(duì)于掛上去的點(diǎn),我們可以直接用上面暴力2的方法統(tǒng)計(jì)答案,復(fù)雜度是log的,那么對(duì)于其他點(diǎn),我們?nèi)绾谓y(tǒng)計(jì)答案呢?

我們可以發(fā)現(xiàn)一個(gè)性質(zhì),就是對(duì)于最底端這個(gè)點(diǎn)向上的其他鏈上的點(diǎn)作為L(zhǎng)CA時(shí),答案只會(huì)出現(xiàn)在這個(gè)點(diǎn)除了重兒子以外的子樹(shù)內(nèi)以及自己,因?yàn)橹劓湹紫碌淖訕?shù)我們剛才已經(jīng)處理過(guò)了。

所以我們的做法就是,對(duì)于每一條重鏈,自頂至底處理,然后我們把式子移個(gè)項(xiàng)

i-len[LCA]<l

我們把這個(gè)點(diǎn)的所有非重兒子所在子樹(shù)中的點(diǎn)的i-len[LCA]全部加進(jìn)以i為下標(biāo)的線段樹(shù)中,然后一直往下合并,那么每到一個(gè)點(diǎn),它就保存了它到重鏈頂端所有LCA的信息,然后我們直接詢問(wèn)掛在這個(gè)點(diǎn)的詢問(wèn)就可以了。

但每次暴力加的復(fù)雜度對(duì)嗎?

樹(shù)上啟發(fā)式合并(DSU on tree)

這個(gè)操作的原理和上面的一模一樣,都是利用了輕重鏈log的性質(zhì)。

主要思想就是,維護(hù)重鏈,輕鏈暴力,考慮一個(gè)點(diǎn)會(huì)被暴力做多少次,它到根的路徑上輕重鏈切換的時(shí)候才會(huì)產(chǎn)生一次,根據(jù)上面的結(jié)論,這是log的。

于是我們?cè)趎log2的時(shí)間內(nèi)做完了這道題。

代碼

#include<iostream> #include<cstdio> #include<cstring> #include<vector> #define N 400002 #define inf 2e9 using namespace std; vector<int>vec[N]; char s[N]; int last,cnt,n,tot,head[N],topp,ls[N*30],rs[N*30],tr[N*30],T[N<<1],len[N],id[N],ch[N][26],fa[N],f[N]; int L[N*30],R[N*30],size[N],top[N],son[N],ans[N],q,rt[N],_id[N],mi[N*30]; inline int rd(){int x=0;char c=getchar();bool f=0;while(!isdigit(c)){if(c=='-')f=1;c=getchar();}while(isdigit(c)){x=(x<<1)+(x<<3)+(c^48);c=getchar();}return f?-x:x; } struct edge{int n,to;}e[N<<1]; struct node{int l,r;}qu[N]; inline void add(int u,int v){e[++tot].n=head[u];e[tot].to=v;head[u]=tot;} inline int newnode(){int x=++topp;tr[x]=inf;ls[x]=rs[x]=0;return x; } void ins(int &cnt,int l,int r,int x){if(!cnt)cnt=++topp,mi[cnt]=inf;mi[cnt]=min(mi[cnt],x);if(l==r)return;int mid=(l+r)>>1;if(mid>=x)ins(L[cnt],l,mid,x);else ins(R[cnt],mid+1,r,x); } int merge(int cnt,int pre,int l,int r){if(!cnt||!pre)return cnt^pre;int p=++topp;mi[p]=min(mi[cnt],mi[pre]);if(l==r)return p;int mid=(l+r)>>1;L[p]=merge(L[cnt],L[pre],l,mid);R[p]=merge(R[cnt],R[pre],mid+1,r);return p; } int prequery(int cnt,int l,int r,int ql,int qr,int x){if(mi[cnt]>=x)return 0;if(l==r)return (l>=ql&&l<=qr)?l:0;int mid=(l+r)>>1;if(mid<qr&&mi[R[cnt]]<x){int num=prequery(R[cnt],mid+1,r,ql,qr,x);if(num)return num;}else if(mid>=ql&&mi[L[cnt]]<x)return prequery(L[cnt],l,mid,ql,qr,x);return 0; } inline void insert(int x,int tag){int p=last,np=++cnt;last=np;len[np]=len[p]+1;ins(T[np],1,n,tag);id[tag]=np;_id[np]=tag;for(;p&&!ch[p][x];p=fa[p])ch[p][x]=np;if(!p)fa[np]=1;else{int q=ch[p][x];if(len[p]+1==len[q])fa[np]=q;else{int nq=++cnt;len[nq]=len[p]+1;memcpy(ch[nq],ch[q],sizeof(ch[nq]));fa[nq]=fa[q];fa[q]=fa[np]=nq;for(;ch[p][x]==q;p=fa[p])ch[p][x]=nq;}} } void ins2(int &cnt,int l,int r,int x,int y){if(!cnt)cnt=newnode();tr[cnt]=min(tr[cnt],y);if(l==r)return;int mid=(l+r)>>1;if(mid>=x)ins2(ls[cnt],l,mid,x,y);else ins2(rs[cnt],mid+1,r,x,y); } int merge2(int cnt,int pre,int l,int r){if(!cnt||!pre)return cnt^pre;int mid=(l+r)>>1;tr[cnt]=min(tr[cnt],tr[pre]);if(l==r)return cnt;ls[cnt]=merge2(ls[cnt],ls[pre],l,mid);rs[cnt]=merge2(rs[cnt],rs[pre],mid+1,r);return cnt; } int query(int cnt,int l,int r,int L,int R,int x){ ///!!!if(l==r)return (l>=L&&l<=R)?l:0;if(tr[cnt]>=x)return 0;int mid=(l+r)>>1;if(mid<R&&tr[rs[cnt]]<x){int num=query(rs[cnt],mid+1,r,L,R,x);if(num)return num;} if(tr[ls[cnt]]<x&&mid>=L)return query(ls[cnt],l,mid,L,R,x);return 0; } void dfs1(int u){size[u]=1;for(int i=head[u];i;i=e[i].n){int v=e[i].to;f[v]=u;dfs1(v);size[u]+=size[v];if(size[v]>size[son[u]])son[u]=v;} } void dfs2(int u){if(!top[u])top[u]=u;if(son[u])top[son[u]]=top[u],dfs2(son[u]);for(int i=head[u];i;i=e[i].n){if(e[i].to!=son[u])dfs2(e[i].to);T[u]=merge(T[u],T[e[i].to],1,n);} } void prework(int cnt,int l,int r,int top){if(l==r){ins2(rt[top],1,n,l,l-len[top]);return;}int mid=(l+r)>>1;if(L[cnt])prework(L[cnt],l,mid,top);if(R[cnt])prework(R[cnt],mid+1,r,top); } void solve(int u){for(int i=head[u];i;i=e[i].n)solve(e[i].to);if(top[u]==u){int x=u; while(x){ for(int i=head[x];i;i=e[i].n){int v=e[i].to;if(v==son[x])continue;prework(T[v],1,n,x);}for(int i=0;i<vec[x].size();++i){int l=qu[vec[x][i]].l,r=qu[vec[x][i]].r;ans[vec[x][i]]=max(ans[vec[x][i]],query(rt[x],1,n,l,r-1,l));}if(son[x])rt[son[x]]=merge2(rt[son[x]],rt[x],1,n);x=son[x];}} } int main(){tr[0]=mi[0]=inf;scanf("%s",s+1);n=strlen(s+1);cnt=last=1;for(int i=1;i<=n;++i)insert(s[i]-'a',i);for(int i=2;i<=cnt;++i)add(fa[i],i);dfs1(1);dfs2(1);q=rd();topp=0;//合并完后的第一類線段樹(shù)不會(huì)新增節(jié)點(diǎn)了,所以把它清空。 for(int i=1;i<=q;++i){qu[i].l=rd();qu[i].r=rd();int x=id[qu[i].r];while(x){vec[x].push_back(i);ans[i]=max(ans[i],prequery(T[x],1,n,qu[i].l,qu[i].r-1,qu[i].l+len[x]));//!!!x=f[top[x]];}}for(int i=1;i<=n;++i)ins2(rt[id[i]],1,n,i,0);solve(1);for(int i=1;i<=q;++i)printf("%d\n",ans[i]?ans[i]-qu[i].l+1:0);return 0; }

轉(zhuǎn)載于:https://www.cnblogs.com/ZH-comld/p/10162320.html

總結(jié)

以上是生活随笔為你收集整理的[BJWC2018]Border 的四种求法(后缀自动机+链分治+线段树合并)的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。

如果覺(jué)得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。

主站蜘蛛池模板: 欧美精品网址 | 国产污污 | 午夜久久久久久久久久 | 国产精品自拍视频一区 | 一区av在线 | 婷婷色婷婷 | 剧情av在线| 在线观看av一区二区 | 丁香av| 男人日女人在线观看 | 久久国产美女 | 欧美国产乱视频 | 精品一区二区亚洲 | 青青草视频免费播放 | 91麻豆精品91久久久久同性 | 久久激情免费视频 | 91爱国产 | 蝌蚪av| 色一情一乱一区二区三区 | 性高潮久久久久久久 | www.九九热| 色偷偷人人澡人人爽人人模 | 我和我的太阳泰剧在线观看泰剧 | 免费看黄色小视频 | 宅男av | 免费看aaaaa级少淫片 | 国产porn| 久久天天躁狠狠躁夜夜av | av免费网站观看 | 日韩一级黄色录像 | 成人极品 | 视频在线播 | 亚洲精品美女久久久 | 欢乐谷在线观看免费播放高清 | 日韩久久久久久久久久 | 久久精品一区二区在线观看 | 在线看黄色片 | 三男一女吃奶添下面 | 六月色婷 | 在线观看色网 | 精品黄网| 99热这里只有精品首页 | 亚洲精品2| 亚洲AV成人无码久久精品同性 | 亚洲高清二区 | 日韩xx视频 | 国产超碰人人模人人爽人人添 | 国内精品久久久久久 | 神马影院午夜伦理 | 久久天天东北熟女毛茸茸 | 婷婷激情五月网 | 澳门黄色网 | 爱操在线 | 欧美视频一区二区三区在线观看 | 2019最新中文字幕 | 国产又粗又猛又爽免费视频 | 精品人妻无码一区二区三区蜜桃一 | 成人午夜在线 | 国产人澡人澡澡澡人碰视频 | 日韩在线一卡 | 精品在线不卡 | 欧美影院在线观看 | 日韩欧美一区二区三区久久婷婷 | 91国在线视频 | 又粗又猛又爽又黄少妇视频网站 | 国产精品久久久久久久久久辛辛 | 蜜桃又黄又粗又爽av免 | 欧美怡红院一区二区三区 | 男生和女生差差的视频 | 理论片高清免费理伦片 | 欧美成一区二区三区 | 在线看日本 | 丰满雪白极品少妇流白浆 | 一区二区高清在线观看 | 久啪视频 | 欧美一区二区人人喊爽 | 日操夜操天天操 | xxxxⅹxxxhd日本8hd| 精品视频在线免费看 | 欧美激情在线免费观看 | 黄色三级三级三级三级 | 免费精品在线观看 | 色综合视频在线观看 | 天天爽av| 成人午夜精品一区二区三区 | 法国空姐电影在线 | 国产精欧美一区二区三区蓝颜男同 | 黑人操日本女人视频 | 国产一区二区不卡在线 | 在线观看wwww | 福利小视频 | 69精品| 黄色男人的天堂 | 看免费的毛片 | 日一日射一射 | 波多野结衣视频在线 | 日韩经典av | 国产av成人一区二区三区 | 日韩av在线播放一区 |