在這個問題中,給定乙個字串s,與乙個整數k,定義s的子串t=s(i, j)是關於第k位的識別子串,滿足以下兩個條件:
1、i≤k≤j。
2、子串t只在s中出現過一次。
例如,s=」banana」,k=5,則關於第k位的識別子串有」nana」,」anan」,」anana」,」nan」,」banan」和」banana」。
現在,給定s,xx希望知道對於s的每一位,最短的識別子串長度是多少,請你來幫助他。
n<=500000
先把字尾數組建出來,然後對於每乙個字尾p,我們可以知道以它為開頭且在s中只出現一次的串的長度區間,設為[l,r]。
對於在[p,p+l-1]中的位置,字尾p對它們答案的貢獻是l。對於[p+l,p+r-1]中的位置pos,字尾p對它們答案的貢獻是pos-p+1。
那麼我們只要用線段樹分別維護一下兩種貢獻的最小值即可。
#include
#include
#include
#include
#include
using namespace std;
const int n=500005;
const int inf=1000000000;
int n,s[n],b[n],c[n],d[n],rank[n*2],sa[n],height[n],pos,mn;
char str[n];
struct treet[n*4];
void get_sa(int n,int
m) while (j<=n)
for (int i=1;i<=n;i++) rank[i]=c[i];
if (t==n) break;
j<<=1;
}for (int i=1;i<=n;i++) sa[rank[i]]=i;
}void get_height(int n)
height[1]=0;
}void build(int d,int l,int r)
void ins1(int d,int l,int r,int
x,int
y,int z)
int mid=(l+r)/2;
if (y
<=mid) ins1(d*2,l,mid,x,y,z);
else
if (x>mid) ins1(d*2+1,mid+1,r,x,y,z);
else ins1(d*2,l,mid,x,mid,z),ins1(d*2+1,mid+1,r,mid+1,y,z);
}void ins2(int d,int l,int r,int
x,int
y,int z)
int mid=(l+r)/2;
if (y
<=mid) ins2(d*2,l,mid,x,y,z);
else
if (x>mid) ins2(d*2+1,mid+1,r,x,y,z);
else ins2(d*2,l,mid,x,mid,z),ins2(d*2+1,mid+1,r,mid+1,y,z);
}void query(int d,int l,int r,int
x)int main()
for (int i=1;i<=n;i++)
return
0;}
bzoj2865 字串識別 字尾自動機 線段樹
description xx在進行字串研究的時候,遇到了乙個十分棘手的問題。在這個問題中,給定乙個字串s,與乙個整數k,定義s的子串t s i,j 是關於第k位的識別子串,滿足以下兩個條件 1 i k j。2 子串t只在s中出現過一次。例如,s banana k 5,則關於第k位的識別子串有 nan...
BZOJ3473 字串 廣義字尾自動機
今天主攻了下sam 好多東西以前都沒理解到 對於這道題 我們建乙個自動機存所有串 每個穿last從1開始 對於自動機上每個點額外記乙個cnt 表示能匹配到這個點的不同串個數 建完對每個串在自動機上匹配 把到的每個點x和par x par par x 的cnt 然後就從父親往兒子傳遞一下 這樣每個點i...
BZOJ 3473 字串 廣義字尾自動機
time limit 20 sec memory limit 256 mb submit 354 solved 160 submit status discuss 給定n個字串,詢問每個字串有多少子串 不包括空串 是所有n個字串中至少k個字串的子串?第一行兩個整數n,k。接下來n行每行乙個字串。一行...