BZOJ 4650 Noi2016 優秀的拆分

2022-08-16 15:39:12 字數 1034 閱讀 3247

題解:求解每個位置向左向右aa串的個數f[x],g[x];

列舉a的長度,每a個位置設乙個關鍵點

每乙個a一定僅且跨越乙個關鍵點

然後求出相鄰關鍵點向前向後的最長公共字首的長度,這會對一段區間的f,g產生影響;

用差分+字首和統計答案

#include#include#include#includeusing namespace std;

const int maxn=40009;

int t;

int n;

struct suffix_array

for(int i=1;i<=m;++i)c[i]=0;

for(int i=1;i<=n;++i)c[x[y[i]]]++;

for(int i=2;i<=m;++i)c[i]+=c[i-1];

for(int i=n;i>=1;--i)sa[c[x[y[i]]]--]=y[i];

swap(x,y);

x[sa[1]]=p=1;

for(int i=2;i<=n;++i)

if(p>=n)break;

m=p;

} }int rank[maxn];

int height[maxn];

void getheight() }

int f[maxn][20];

void stinit()

void sainit()

}a[2];

int tb[2][maxn];

int main()

}// for(int i=1;i<=n;++i)printf("%d ",tb[0][i]);

// cout

// cout

long long ans=0;

for(int i=1;iprintf("%lld\n",ans);

} return 0;

}

bzoj 4650 Noi2016 優秀的拆分

原來只會兩個log平衡樹合併。後來圍觀claris在uoj群上秒題後會了這道題。列舉a b 的長度l,然後列舉i kl,考慮字首i,i l和字尾i 1,i l 1,求出字首的lcp和字尾的lcp,然後合法的方案就在乙個方案內。差分一下即可。注意要避免重複。ac 如下 include include ...

BZOJ4650 Noi2016 優秀的拆分

設 f i 表示以 i 結尾的square個數,g i 表示以 i 開頭的square個數,則 ans sum f ig 列舉square中長度的一半 l 每 l 步取乙個關鍵點,那麼每個該長度的square的肯定恰好經過兩個相鄰的關鍵點,且位置差距為 l 的字元一一匹配。所以相鄰關鍵點之間通過字尾...

BZOJ4560 NOI2016 優秀的拆分

bzoj 洛谷考慮乙個形如 aabb 的串是由兩個形如 aa 的串拼起來的 那麼我們設 f i 以位置 i 為結尾的形如 aa 串的個數 g i 以位置 i 為開頭的形如 aa 串的個數 therefore ans sum nf i g i 1 題目的難點轉化為求 f,g 但是,其實我們只要 o n...