LOJ 6070基因 回文樹 分塊

2021-09-26 13:39:58 字數 1817 閱讀 5675

提交鏈結 題解

分為n

\sqrt

n​個塊,每個塊預處理出起點到 n 的回文樹,需要儲存的資訊有區間的回文串種類個數、區間的某種結點出現的最早位置以及區間的最長回文字首對應的結點

後兩個都是為了向前插入準備的

這是因為,如果向前插入的過程中,產生的乙個新的結點,我們需要看這個結點在區間內是否出現過,

此外,向前插入,需要從最長回文字首開始

這道題需要對回文樹有深入的理解,並且要用到翁文濤在**裡講的另一種快速插入的方式 qui

ckquick

quic

k,所以最好對**有深入理解才能解決本題

**

#include

#define n 100010

#define inf 0x3f3f3f3f

#define eps 1e-6

#define pi 3.141592653589793

#define mod 1000000007

#define p 1000000007

#define ll long long

#define pb push_back

#define fi first

#define se second

#define cl clear

#define si size

#define lb lower_bound

#define ub upper_bound

#define bug(x) cerr<

#define sc(x) scanf("%d",&x)

#define scc(x,y) scanf("%d%d",&x,&y)

#define sccc(x,y,z) scanf("%d%d%d",&x,&y,&z)

using namespace std;

typedef pair<

int,

int> pp;

char s[n]

;int p[

320]

[n],ans[

320]

[n],pos[

320]

[n];

int vis[n]

,fail[n]

,len[n]

,a[n]

,nxt[n][26

],qic[n][26

],last,head,cnt,t;

void

init()

inline

intnewnode

(int l)

void

exback

(int l,

int i)

last=nxt[last]

[c];

if(len[last]

==i-l+

1) head=last;

}void

exfront

(int i,

int r)

head=nxt[head]

[c];

if(len[head]

==r-i+

1) last=head;

}int

main()

}int ans=0;

while

(m--)}

else

}printf

("%d\n"

,ans);}

}

hdu6070 線段樹 二分

題意給你乙個區間,讓你找,區間種類數 區間長度最小是多少。思路先公式化簡 size r l 1 mid size l 1 mid r mid mid是二分的值 對於每乙個元素a i 他能影響的區間是,last a i 1 到i last表示這個這個元素上一次出現的位置 他能讓這個區間的種類數 1,由...

線段樹 二分 HDU6070

題目讓我們求type l,r r l 1 的最小,顯然可以用01分數規劃,來二分求最小答案。所以我們從左往右移動端點,來統計種類。線段樹來維護type l,r l mid的值。include using namespace std const int n 1e6 7 const double eps...

hdu 6070 二分答案 線段樹

題意 區間價值為 區間元素種類數 區間長度 問最小價值的區間是?思路 直接求解很困難,考慮二分答案判斷,注意這題的關鍵是將二分答案後的不等式進行變換,如官方題解。二分答案 mid,檢驗是否存在乙個區間滿足 size l,r r l 1 mid,也就是 size l,r mid l mid r 1 之...