bzoj4566 HAOI2016 找相同字元

2021-07-13 12:29:35 字數 1544 閱讀 4015

time limit: 20 sec memory limit: 256 mb

submit: 113 solved: 64

[submit][status][discuss]

description

給定兩個字串,求出在兩個字串中各取出乙個子串使得這兩個子串相同的方案數。兩個方案不同當且僅當這兩

個子串中有乙個位置不同。

input

兩行,兩個字串s1,s2,長度分別為n1,n2。1 <=n1, n2<= 200000,字串中只有小寫字母

output

輸出乙個整數表示答案

sample input

aabb

bbaa

sample output

把兩個串用乙個很大的字元連線起來,求乙個字尾陣列。

考慮怎樣暴力的算答案。 在r

ank 陣列中從前往後列舉起點,對於每個列舉的起點,都暴力的往後掃,掃的過程中維護乙個he

ight

的最小值。每到乙個點的時候,如果這個點跟起點不屬於乙個串,就將答案加上當前的最小值,這樣是o(

n2) 的(注釋的**就是。。)

考慮這個還能怎麼算。可以發現我們是維護he

ight

的最小值。那麼我們可以按照he

ight

從大到小的順序掃,這樣每次需要用的就是當前的he

ight

。 掃的過程中用並查集維護一下每個串分別對哪些串有貢獻的(也就是he

ight

陣列的貢獻)。

用乘法原理算一下當前的he

ight

會有多少貢獻。就是用當前的he

ight

乘上這個串和上乙個串分別對於兩個兩個不同的原串的乘積的和。

#include

#include

#include

#include

using

namespace

std;

#define ll long long

const

int n=400010;

ll ans;

char ss[n];

int n,m,len[2],sa[n],c[n],rank[n],height[n],t1[n],t2[n],s[n],fa[n],st[n],en[n],a[n];

inline

bool cmp(int *y,int p,int q,int k)

inline

void build_sa()

}inline

void build_height()

}inline

bool cmp(int x,int y)

inline

int find(int x)

inline

void calc(int x)

int main()

sort(a,a+n,cmp);

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

}

BZOJ4566 Haoi2016 找相同字元

bzoj4566 haoi2016 找相同字元 給定兩個字串,求出在兩個字串中各取出乙個子串使得這兩個子串相同的方案數。兩個方案不同當且僅當這兩個子串中有乙個位置不同。兩行,兩個字串s1,s2,長度分別為n1,n2。1 n1,n2 200000,字串中只有小寫字母 輸出乙個整數表示答案 aabb b...

BZOJ4566 HAOI2016 找相同字元

bzoj luogu 首先把兩個串拼在一起跑字尾陣列。中間插入乙個沒有出現過的字元。求完字尾陣列之後考慮 o n 2 暴力統計 列舉前乙個串和後乙個串的兩個位置,ans lcp i,j 現在改為把一共 2n 個字尾按 rank 順序插入,每插入乙個字尾,統計與其不在同乙個串裡的字尾的貢獻。發現可以單...

bzoj4566 Haoi2016 找相同字元

time limit 20 sec memory limit 256 mb給定兩個字串,求出在兩個字串中各取出乙個子串使得這兩個子串相同的方案數。兩個方案不同當且僅當這兩 個子串中有乙個位置不同。兩行,兩個字串s1,s2,長度分別為n1,n2。1 n1,n2 200000,字串中只有小寫字母 輸出乙...