等差子串行 雜湊 權值線段樹

2021-10-02 18:12:15 字數 1991 閱讀 8722

首先我們肯定只需要找len

=3len=3

len=

3的情況

由於是1−n

1-n1−

n的序列,因此我們考慮對乙個數x

xx維護[x−

len,

x−1]

,[x+

1,x+

len]

[x-len,x-1],[x+1,x+len]

[x−len

,x−1

],[x

+1,x

+len

]的01

0101

串,(0

00表示在x

xx之前沒出現,1

11表示在x

xx之前出現了,len

=min

(x−1

,n−x

)len=min(x-1,n-x)

len=mi

n(x−

1,n−

x));如果這兩個01

0101

串對應位置不同,那麼必有滿足的等差序列,因為x+d

,x−d

x+d,x-d

x+d,x−

d乙個在前面出現,另乙個前面沒出現,那麼一定在x

xx後面出現,因此每讀入乙個數,就丟進權值線段樹中,維護01

0101

串的雜湊值

#include

#define m 20009

#define ll unsigned long long

using

namespace std;

struct treetr[m*4]

;int n,t,a[m]

;ll mi[m]

;const

int h=

13331

;const ll mod=

998244353

;int

read()

for(

;isdigit

(ch)

;ch=

getchar()

) re=

(re<<3)

+(re<<1)

+ch-

'0';

return re*f;

}void

pushup

(int k,

int l,

int r,

int mid)

void

update

(int k,

int l,

int r,

int val)

int mid=

(l+r)

>>1;

if(val<=mid)

update

(k<<

1,l,mid,val)

;else

update

(k<<1|

1,mid+

1,r,val)

;pushup

(k,l,r,mid);}

ll query

(int k,

int l,

int r,

int ql,

int qr,

int vis)

intmain()

ll fx=

query(1

,1,n,x-len,x-1,

0); ll fy=

query(1

,1,n,x+

1,x+len,1)

;if(fx!=fy)

update(1

,1,n,x);}

printf

("n\n");

end:;}

return0;

}

使用goto的時候,記得讀完資料,否則會莫名ml

權值線段樹套序列線段樹

p3380 模板 二逼平衡樹 樹套樹 主要思路如下 外層為權值線段樹,內層為動態開點線段樹,也就是每個權值線段樹上的節點開乙個動態開點線段樹。外層的權值線段樹支援查詢排名,內層的線段樹限制了區間。實際上就是在普通權值線段樹上查詢的價值變成了在其線段樹上區間查詢返回的值。對於這道模板題,我們先寫幾個函...

權值線段樹

維護全域性的值域資訊,每個節點記錄的是該值域的值出現的總次數。使用二分的思想 離散化的時候,需要用到 支援查詢全域性k小值,全域性rank,前驅,後繼等。單詞操作時間複雜度為o logn 空間複雜度為o n 相對於平衡樹的優勢 簡單,速度快 劣勢 值域較大時,我們需要離散化,變成離線資料結構 我認為...

權值線段樹

include using namespace std int n,m,tre 10003 4 laz 10003 4 void pushdown int num void update int num,int le,int ri,int x,int y,int z pushdown num int...