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,字串中只有小寫字母 輸出乙...