題意:給乙個字串,對於每個位置i,求出最短滿足的子串[l,r]使得i∈[l,r]且這個子串只出現一次,輸出這個子串的長度
神(shui)題,ac後看了下別人的code發現全都是字尾陣列(難看)
可能是因為我太弱了所以只想到sam的演算法
做法:建立sam,求出parent樹,預處理倍增,讓後就可以o(lg n)查詢乙個字串的出現次數了
接下來,我們對於每個l∈[1,n],我們求出乙個最小的r使得[l,r]在整個串裡面只出現一次
那麼對於每個點i,ans[i]有兩種情況:
1.i被乙個最短的區間[lj,rj]覆蓋,那麼我們可以
把這些l,r區間按長度從大到小排序,並且用線段樹區間覆蓋
2.有可能是乙個區間[lj,rj](rj
對於這種情況,我們把所有區間按r排序,對於i,我們用二分找到最大的j使得rj
兩種情況取較小就可以了
**很長很醜,跑的也很慢。。。。
#include#include#include#define n 1000010
#define f f[0]
using namespace std;
struct pr r[n];
int f[20][n],s[n][26],mx[n],sz[n],d[n],m[n],n;
int v[n],r[n],m=1,cnt=1,last=1,a[n],pos[n],t[n<<2];
char str[n];
inline bool c1(pr a,pr b)
inline int extend(char c,int& o)
}inline void build()
}int gsz(int l,int r)
return sz[x];
}void cover(int l,int r,int x,int l,int r,int k)
if(t[x])
int mid=l+r>>1;
if(l<=mid) cover(l,mid,x<<1,l,r,k);
if(mid>1;
if(p<=mid) return gcover(l,mid,x<<1,p);
else return gcover(mid+1,r,x<<1|1,p);
}int main();
if(++l>r) ++r;
} sort(r+1,r+1+n,c2); t[1]=n;
for(int i=1;i<=n;++i)
if(r[i].r<=n) cover(1,n,1,r[i].l,r[i].r,r[i].r-r[i].l+1);
for(int i=1;i<=n;++i)
a[i]=gcover(1,n,1,i);
sort(r+1,r+1+n,c1); m[0]=-n;
for(int i=1;i<=n;++i) m[i]=max(m[i-1],r[i].l);
for(int i=1;i<=n;++i)
printf("%d\n",min(a[i],i-m[l]+1));
}}
Jzoj2921 NOI2012模擬題 字串識別
題意 給乙個字串,對於每個位置i,求出最短滿足的子串 l,r 使得i l,r 且這個子串只出現一次,輸出這個子串的長度 神 shui 題,ac後看了下別人的code發現全都是字尾陣列 難看 可能是因為我太弱了所以只想到sam的演算法 做法 建立sam,求出parent樹,預處理倍增,讓後就可以o l...
NOI 2012 騎行川藏
題意 在滿足 i vi 0且 n i 1k isi vi t i 2 e 前提下最小化 n i 1s i vi 學習了一下拉格朗日橙子乘子法。對於函式f x1,x 2,xn 和g x1,x 2,xn 在滿足g c c為 常數 的前提下求 f 的最小值。我們直觀地想象,所有極值點一定滿足 f g 令f...
NOI2012 騎行川藏
noi2012 騎行川藏 思路一 二分導數 考慮 價效比 即花費單位能量縮短的時間。如果我們給每一段隨機分配乙個速度,再調整 那麼一定選擇價效比最高的調整,或者把價效比較低的能量取回,再分配 而價效比隨著能量分配,會越來越低 可以發現的是,最後所有的n段的價效比一定都相同!如果存在不同的,那麼一定可...