1. 程式人生 > >bzoj1396 識別子串

bzoj1396 識別子串

node div tro xtend struct 我們 strong 線段 數列

題解:

首先我們知道對於size==1的點是只出現一次的

存疑:為什麽新增點不會size==1

那麽問題就變成區間取等差數列,區間取最小值

分別線段樹維護就可以了

代碼:

#include <bits/stdc++.h>
#define IL inline
#define ll long long
#define rint register int
#define rep(i,h,t) for (rint i=h;i<=t;i++)
#define dep(i,t,h) for (rint i=t;i>=h;i--)
using namespace
std; const int INF=1e9; const int N=3e5; char s[N]; int size[N],len[N],ch[N][26]; int lst=1,node=1,t[N],a[N],fa[N],pos[N],pl; void extend(int c) { int f=lst; if (ch[f][c]&&len[ch[f][c]]==len[f]+1) { lst=ch[f][c]; return; } int p=++node; lst=p; len[p]=len[f]+1
; //size[p][pl]=1; while (f&&!ch[f][c]) ch[f][c]=p,f=fa[f]; if (!f) { fa[p]=1; return;}; int x=ch[f][c],y=++node; if (len[f]+1==len[x]) {fa[p]=x; node--;return;}; len[y]=len[f]+1; fa[y]=fa[x]; fa[x]=fa[p]=y; memcpy(ch[y],ch[x],sizeof(ch[x])); while (f&&ch[f][c]==x) ch[f][c]=y,f=fa[f]; } IL
int min(int x,int y) { if (x>y) return(y); else return(x); } IL int max(int x,int y) { if (x<y) return(y); else return(x); } IL void minn(int &x,int y) { if (x>y) x=y; } IL void maxn(int &x,int y) { if (x<y) x=y; } const int N1=N*4; struct sgt{ int lazy1[N1],lazy2[N1]; sgt() { rep(i,0,N1-1) lazy1[i]=lazy2[i]=INF; } #define mid ((h+t)/2) IL void down(int x,int h,int t) { minn(lazy1[x*2],lazy1[x]); minn(lazy1[x*2+1],lazy1[x]-(mid-h+1)); minn(lazy2[x*2],lazy2[x]); minn(lazy2[x*2+1],lazy2[x]); } void change1(int x,int h,int t,int h1,int t1,int k) { if (h1<=h&&t<=t1) { minn(lazy1[x],k); return; } down(x,h,t); if (h1<=mid) change1(x*2,h,mid,h1,t1,k); if (mid<t1) change1(x*2+1,mid+1,t,h1,t1,k-(mid-h+1)); } void change2(int x,int h,int t,int h1,int t1,int k) { if (h1<=h&&t<=t1) { minn(lazy2[x],k); return; } down(x,h,t); if (h1<=mid) change2(x*2,h,mid,h1,t1,k); if (mid<t1) change2(x*2+1,mid+1,t,h1,t1,k); } int query(int x,int h,int t,int pos) { if (h==t) { return(min(lazy1[x],lazy2[x])); } down(x,h,t); if (pos<=mid) return(query(x*2,h,mid,pos)); else return(query(x*2+1,mid+1,t,pos)); } }S; int main() { freopen("1.in","r",stdin); freopen("1.out","w",stdout); ios::sync_with_stdio(false); cin>>s; int l=strlen(s); int n=l; rep(i,1,l) extend(s[i-1]-a),size[lst]++,pos[lst]=i; rep(i,1,node) t[len[i]]++; rep(i,1,node) t[i]+=t[i-1]; rep(i,1,node) a[t[len[i]]--]=i; dep(i,node,1) { int x=a[i]; size[fa[x]]+=size[x]; } rep(i,1,node) if (size[i]==1) { S.change1(1,1,n,pos[i]-len[i]+1,pos[i]-len[fa[i]],len[i]); if (fa[i]) S.change2(1,1,n,pos[i]-len[fa[i]]+1,pos[i],1+len[fa[i]]); } rep(i,1,n) cout<<S.query(1,1,n,i)<<endl; return 0; }

bzoj1396 識別子串