設\(dp[i]\)表示以\(i\)開頭的答案
首先預處理如果\(i\)作為區間開頭,那麼他的右端點最近可以到**
那麼\(s[i]\)可以選也可以不選
若不選\(dp[i]+=dp[i-1]\)
若選\(dp[i]+=suf[r[i]+1]+d1-r[i]+1(d1代表匹配串的長度)\)
不選\(s[i]\)很容易解釋
選\(s[i]\)首先可以只有乙個區間那麼就是\(d1-r[i]+1\)
若有多個區間則為\(dp[r[i]+1]+dp[r[i]+2].....+dp[n]\)
因為以\(s[i]\)開頭的區間可以為\([i,r[i]],[i,r[i]+1]....\)
用字尾和優化一下即可
#includeusing namespace std;
#define fi first
#define se second
typedef long long ll;
typedef unsigned long long ull;
typedef pairpdi;
const ll inf=0x3f3f3f3f3f3f3f3f;
const int maxn=1e6+5,mod=99824353;
char s[maxn],t[maxn];
int r[maxn];
int suf[maxn];
ll dp[maxn];
ull pre[maxn],temp,power[maxn],base=233;
ull get_hash(int l,int r)
int main()
if(i<=d2)
}int pos=0;
for(int i=d1-d2+1;i>=1;i--)
r[i]=pos;
}ll ans=0;
for(int i=d1;i>=1;i--)
suf[i]=(suf[i+1]+dp[i])%mod;
}printf("%lld\n",(dp[1]+1)%mod);
return 0;
}
單詞檢索 題解
呃 這題,真的不想說話。給出n個由小寫字母組成的字串,統計至少在m個字串中出現過的長度為l的字串數 n,m 2000,l i,l 1000 n m 2000,l i,l 1000 一看,就知道是雜湊 對於每個長度為l的串,都雜湊一下 還要記得o 1 o 1 推下乙個雜湊值,對於同乙個模板中出現多次的...
題解 字首單詞
一組單詞是安全的,當且僅當不存在乙個單詞是另乙個單詞的字首,這樣才能保證資料不容易被誤解。現在你手上有乙個單詞集合,你需要計算有多少個子集是安全的。注意空集永遠是安全的。首先 設dp i 表示前i個集合以i結尾的集合數 核心 dp i dp j 1 j但是問題在於與j不互為字首的單詞不一定與i不互為...
DP 單詞的劃分
題目描述 有乙個很長的由小寫字母組成字串。為了便於對這個字串進行分析,需要將它劃分成若干個部分,每個部分稱為乙個單詞。出於減少分析量的目的,我們希望劃分出的單詞數越少越好。你就是來完成這一劃分工作的。輸入 第一行,乙個字串。字串的長度不超過300 第二行乙個整數n,表示單詞的個數。n 100 第3 ...