回文樹練習題

2021-08-27 14:09:23 字數 4406 閱讀 2837

貼(改)模板大集合系列

大概包括了pam的這些問題:

1.sz的意義:本質不同的回文子串個數

2.cnt的意義:當前回文子串出現的次數

3.num的意義:靠最右邊的回文子串個數、新加乙個字元產生的回文子串個數、暴力fail的層數

4.half的意義:長度小於等於當前回文子串的一半的回文字尾的節點

5.支援兩邊加字元的回文自動機的做法:維護一左一右兩個last

tsinsen a1280

問題描述

順序和逆序讀起來完全一樣的串叫做回文串。比如acbca是回文串,而abc不是(abc的順序為「abc」,逆序為「cba」,不相同)。

輸入長度為n的串s,求s的最長雙回文子串t,即可將t分為兩部分x,y,(|x|,|y|≥1)且x和y都是回文串。

#include using namespace std;

typedef long long ll;

const int maxn=100007;

char s[maxn];

struct pam

cnt[sz]=0;

len[sz]=l;

return sz++;

}void init()

int getfail(int x)

void insert(char ch)

last=next[u][c];

cnt[last]++;

}void count()

}}pam;

int pre[maxn];

int main()

printf("%lld\n",ans);

}

tsinsen a1393

問題描述

給你乙個長度 n (1 ≤ n ≤ 2·106) 的只由小寫字母組成的字串s。

我們考慮s的所有連續且回文的子串集合p。位置不同但內容相同的兩個串算作不同。

問從p中選出兩個串且他們在s中有公共位置的方法數有幾個?

#include using namespace std;

typedef long long ll;

const int mod=51123987;

const int inv2=(mod+1)/2;

const int maxn=2000007;

char s[maxn];

struct pam

cnt[sz]=0;

len[sz]=l;

return sz++;

}void init()

int getfail(int x)

void insert(char ch)

last=next[u][c];

cnt[last]++;

}ll count()

return ret;

}}pam;

ll suf[maxn];

int main()

ll tot=suf[0]*(suf[0]-1+mod)%mod*inv2%mod;

pam.init();

ll rev=0;

for(int i=0;iacm-icpc 2018 南京賽區網路預賽 i.skr

問題描述

求本質不同回文子串的hash和

#include using namespace std;

typedef long long ll;

const int mod=1e9+7;

const int maxn=2000007;

char s[maxn];

ll pw[maxn];

ll ans=0;

struct pam

cnt[sz]=0;

len[sz]=l;

val[sz]=0;

return sz++;

} void init()

int getfail(int x)

void insert(char ch)

else

ans=(ans+val[v])%mod;

fail[v]=next[getfail(fail[u])][c];

next[u][c]=v;

} last=next[u][c];

cnt[last]++;

} void count()

}}pam;

int main()e[maxn];

int head[maxn];

int cnt;

void init()

void addedge(int u,int v)

struct pam

cnt[sz]=0;

len[sz]=l;

return sz++;

} void init()

int getfail(int x)

void insert(char ch)

last=next[u][c];

cnt[last]++;

} void count()

}}pam;

int vis[maxn];

int ans;

void dfs(int u)

for(int i=head[u];~i;i=e[i].next)

}int main()

cnt[sz]=0;

len[sz]=l;

return sz++;

} void init()

int getfail1(int x)

int getfail2(int x)

void insertbefore(char ch)

last1=next[u][c];

cnt[last1]++;

if(len[last1]==r-l+1)last2=last1;

} void insertafter(char ch)

last2=next[u][c];

cnt[last2]++;

if(len[last2]==r-l+1)last1=last2;

} void count()

}}pam;

int main()

else if(op==2)

else if(op==3)

else

} }}

cf 245h

題目描述

給乙個長為5000的字串,多次查詢區間回文子串個數

#include using namespace std;

typedef long long ll;

const int maxn=5007;

char s[maxn];

struct pam

cnt[sz]=0;

len[sz]=l;

return sz++;

} void init()

int getfail(int x)

void insert(char ch)

last=next[u][c];

cnt[last]++;

} void count()

}}pam;

int n;

int ans[5003][5003];

int main()

cnt[sz]=0;

len[sz]=l;

dp[sz]=0;

sum[sz]=0;

return sz++;

} void init()

int getfail(int x)

int gethalf(int x,int l)

void insert(char ch)

last=next[u][c];

cnt[last]++;

} void count()

}}pam;

ll ans;

int n;

int main()

cnt[sz]=0;

len[sz]=l;

return sz++;

} void init()

int getfail(int x)

void insert(char ch)

last=next[u][c];

cnt[last]++;

} void count()

}}pam1,pam2;

ll ans;

int n,m;

void dfs(int u1,int u2)

}int main()

pam1.count();

for(int i=0;ipam2.count();

ans=0;

dfs(0,0);

dfs(1,1);

printf("%lld\n",ans);

}

線段樹練習題一

線段樹練習題一 description 桌子上零散地放著若干個盒子,桌子的後方是一堵牆。如右圖所示。現在從桌子的前方射來一束平行光,把盒子的影子投射到了牆上。問影子的總寬度是多少?分析 給線段樹每個節點增加乙個域cover。cover 1表示該結點所對應的區間被完全覆蓋,cover 0表示該結點所對...

線段樹練習題二

線段樹練習題二 description 桌子上零散地放著若干個不同顏色的盒子,桌子的後方是一堵牆。如右圖所示。問從桌子前方可以看到多少個盒子?假設人站得足夠遠 輸入時,由底向上,從左到右 分析 cover 0表示該區間由多種顏色組成。cover 0表示該區間只有一種單一的顏色cover,最後用個桶統...

目錄 線段樹練習題

自己寫過的一點點題的目錄 就寫過這麼一點點題還需要目錄?持續更新中 假的 關於線段樹相關知識,大佬部落格講的非常好 1.poj2528 線段樹 離散化 題目位址 蒟蒻題解 2.sdoj2790 線段樹區間整除 題目位址 蒟蒻題解 3.hdu2795 2018 07 28校賽 線段樹入門2 c 線段樹...