Codeforces 235C Cyclical Quest (后缀自动机)
生活随笔
收集整理的這篇文章主要介紹了
Codeforces 235C Cyclical Quest (后缀自动机)
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
題目鏈接: https://codeforces.com/contest/235/problem/C
題解:
對大串建后綴自動機
對詢問串復制拆環。這里一定要注意是復制一個循環節不是復制整個串!循環節是要整除的那種
然后要做的實際上是在大串上跑,每經過一個點求出當前的最長公共子串,如果大于等于\(n\)的話,則向上跳Parent樹找到\(n\in [minlen[v],maxlen[v]]\)的那個祖先\(v\)
這玩意直接做復雜度是錯的(雖然貌似網上有直接做過了的),但是我們可以遞推!
考慮遞推,實際上就是維護一個長度為\(m\)(詢問串長度)的隊列,每次刪掉第一個字符(就是判斷如果當前最長公共子串長\(=n\)就變成\(n-1\), 如果需要的話跳到父親),然后每次長度達到\(n\)時\(ans+=len[u]\)即可。
代碼
//Love and Freedom. #include<cstdio> #include<cmath> #include<algorithm> #include<cstring> #define ll long long #define inf 20021225 #define N 100010 using namespace std;int fa[N<<1],val[N<<1][2],n; int find(int x){return x==fa[x]?x:fa[x]=find(fa[x]);} struct poi{int x,y,ax,ay;}a[N]; bool cmp1(poi x,poi y){return x.x<y.x;} bool cmp2(poi x,poi y){return x.y<y.y;} void merge(int x,int y) {int fx=find(x),fy=find(y);val[fx][0]+=val[fy][0]; val[fx][1]+=val[fy][1];fa[fy]=fx; } int main() {scanf("%d",&n);for(int i=1;i<=n;i++)scanf("%d%d",&a[i].x,&a[i].y);int xx=0,yy=0;sort(a+1,a+n+1,cmp1);for(int i=1;i<=n;i++){if(a[i].x!=a[i-1].x) ++xx;a[i].ax=xx; }sort(a+1,a+n+1,cmp2);for(int i=1;i<=n;i++){if(a[i].y!=a[i-1].y) ++yy;a[i].ay=yy;}for(int i=1;i<=xx;i++) fa[i]=i,val[i][0]=1;for(int i=1;i<=yy;i++) fa[i+xx]=i+xx,val[i+xx][1]=1;for(int i=1;i<=n;i++) merge(a[i].ax,a[i].ay+xx);ll ans=0;for(int i=1;i<=xx+yy;i++)if(fa[i]==i) ans+=1ll*val[i][0]*val[i][1];printf("%lld\n",ans-n);return 0; }總結
以上是生活随笔為你收集整理的Codeforces 235C Cyclical Quest (后缀自动机)的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: BZOJ 4032 luogu P411
- 下一篇: BZOJ 2806 Luogu P402