洛谷2375 BZOJ 3670動物園題解

2022-05-20 12:13:12 字數 1155 閱讀 8567

題目鏈結

洛谷鏈結

我們發現題目要我們求的num[i]東西本質上其實是

求有多少以i結尾的非字首且能與字首匹配的字串,而且要求字串長度小於(i/2)

我們先不考慮字串長度的限制,看所有以i結尾的非字首且能與字首匹配的字串如何計數

考慮到kmp演算法的next陣列求解的過程,大家應該都想到i結尾的非字首且能與字首匹配的字串的總數就是next[i]跳到0的所跳的次數

為什麼是這樣的呢?

如上圖所示,其中綠色的串與紅色的串是匹配的,若還要尋找匹配的串

不難發現所有以紅色結尾處結尾所能匹配的串都是滿足要求的

從上面的圖不難發現以上結論是對的

具體求解時,我們先求一遍next陣列,若next[i]為0,則不存在這樣的字串,如果大於0,則令num[i]=dep[next[i]]+1

但是我們還要考慮長度小於i/2這乙個限制

乙個樸素的想法就是next不停跳知道小於i/2為止,但這樣複雜度是nlogn,tle

所以我們要在做一遍魔改版kmp,求的是i結尾的非字首且能與字首匹配而且長度小於i/2的最長字串

num[i]=dep[next2[i]]+1

魔改版kmp的求解過程與kmp類似,只是加了一句while(next[j]>i/2) j=next[j]

附上**

# include# include

# include

# include

# include

const

int mod = 1e9 + 7

;const

int mn = 1100005

;int

n,ans,n;

char

s[mn];

intnxt[mn],dep[mn];

intmain()

/*for(int i=1;i<=n;i++)

printf("%d ",nxt[i]);

*/for(int i=2,j=0;i<=n;i++)

printf(

"%d\n

",ans);

}return0;

}

洛谷 P2375 NOI2014 動物園

其實對於乙個sum i 其值就等於sum next i sum next next i 1,然後我們可以記憶化,然後題目裡又有乙個限制,就是前字尾不能重合,那我們就找到最大但是不重合的那種情況,然後往小了列舉就好了.最後答案說要取模,所以不要忘了 ljx xhy yyq 排名無先後 1 includ...

洛谷P2375 NOI2014 動物園

題目大意 求出乙個字串 s 每一位的 num i 最多 5 組詢問,s leqslant10 6 num i 定義為 s 中長度不超過 lfloor dfrac i2 rfloor 的 border 的個數 題解 類似 kmp 發現乙個字串 border 的 border 一定是原串的 border...

洛谷 P1057 傳球遊戲 動規

題目大意 乙個長度為n的閉環,從乙個點出發,經過m條邊後 無方向 回到出發點,求方案數。題目分析 這道題我用的動規,從i出發,經過k步,到達j點的方案數為 i,j,k i,j,k i,j,k 可得狀態轉移方程 i,j,k i,j 1,k 1 i,j 1,k 1 i,j,k i,j 1,k 1 i,j...