题解:
首先我们知道对于size==1的点是只出现一次的
存疑:为什么新增点不会size==1
那么问题就变成区间取等差数列,区间取最小值
分别线段树维护就可以了
代码:
#include#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) x=y;}IL void maxn(int &x,int y){ if (x >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< <