BZOJ 2124等差子串行 線段樹 hash

2022-05-14 05:30:07 字數 2548 閱讀 8603

【題目描述 description】

給乙個 1 到 n 的排列,詢問是否存在 1<=p1=3),使得 ap1,ap2,ap3,…aplen 是乙個等差序列。

【輸入描述 input description】

輸入的第一行包含乙個整數 t,表示組數。

下接 t 組資料,每組第一行乙個整數 n,每組第二行為乙個 1 到 n 的排列, 數字兩兩之間用空格隔開。

【輸出描述 output description】

對於每組資料,如果存在乙個等差子串行,則輸出一行「y」,否則輸出一 行「n」。

【樣例輸入 sample input】

1 3 2

3 2 1

【樣例輸出 sample output】ny

【資料範圍及提示 data size & hint】

對於5%的資料,n<=100,對於30%的資料,n<=1000,對於100%的資料,n<=10000,t<=7

【解題思路】

首先宣告,此題開始並沒有什麼思路,只找到乙個o(n^2)的演算法,然而這並沒有什麼卵用。

老師明示暗示我要我用線段樹去做,我苦思冥想沒有想出來,於是就抄了題解。

題解是這樣的,列舉等差中項,用一顆線段樹去維護那些值選了,那些值沒選,構成乙個01串之後求乙個雜湊值。

如果出現中項左邊的hash值和右邊的hash值不一樣的情況,就說明存在等差數列,因為證明有乙個值在中項左邊已經選過,並且與其對應的值在中項右邊還沒有選。

插入o(logn),查詢o(logn),掃一遍o(n)整體o(ologn);

**略醜

#include#include

#include

using

namespace

std;

const

int maxn=10000+10, mod=100000007

;int

xp[maxn],a[maxn],n,v,t;

long

long sumv[4*maxn][2

];//

sumv[i][0] 代表從左邊掃的值,sumv[i][1]代表從右邊掃的值

void updata(int u,int l,intr)}

long

long query(int node,int l,int r,int a,int b,int

x)int

main()

}v=x;

updata(

1,1,n);

} if (flag) printf("

y\n"

);

else printf("

n\n"

); }

}

以上為堆狀線段樹,由於我一直喜歡用結構體,所以就又打了乙個,然後發現記憶體時間**複雜度都比堆要差,大概是因為要建樹和結構體太大的緣故。線段樹的種類的確要視題目而定。

1 #include2 #include3 #include4

using

namespace

std;

5const

int maxn=10000+10,mod=100000007;6

struct

treetr[maxn*2][2

];10

//tr[now][0]代表從左往右, tr[now][1]代表從右往左

11int

cnt,n,t,xp[maxn],a[maxn];

1213

void build(int now,int l,int

r)23

24long

long query(int now,int l,int r,int

x)34

35void insert(int now,int

x)40

int mid=(tr[now][0].l+tr[now][0].r)>>1;41

if (x<=mid) insert(tr[now][0

].lch,x);

42if (x>=mid+1) insert(tr[now][0

].rch,x);

43int l=tr[now][0].l,r=tr[now][0

].r;

44 tr[now][0].sum=((tr[tr[now][0].lch][0].sum*xp[r-mid])%mod

45 +tr[tr[now][0].rch][0].sum)%mod;

46 tr[now][1].sum=((tr[tr[now][1].rch][1].sum*xp[mid-l+1])%mod

47 +tr[tr[now][1].lch][1].sum)%mod;48}

4950

intmain()

68 insert(1

,x);69}

70if (flag) printf("

y\n"

);71

else printf("

n\n"

);72

}73 }

BZOJ2124 等差子串行

挺厲害的題 我們考慮當前加入了第i個數,為x,那麼我們可以維護一下哪個數出現過,出現過為1,沒出現為0,那麼加入x的時候我們只需要判斷以x為中心的極長子串是否是回文串即可 用乙個樹狀陣列維護兩個方向的雜湊值即可 include include include include include incl...

bzoj 2124 等差子串行

description 給乙個1到n的排列,詢問是否存在1 p1 p2 p3 p4 p5 plen n len 3 使得ap1,ap2,ap3,aplen是乙個等差序列。input 輸入的第一行包含乙個整數t,表示組數。下接t組資料,每組第一行乙個整數n,每組第二行為乙個1到n的排列,數字兩兩之間用...

BZOJ 2124 等差子串行

給乙個1到n的排列,詢問是否存在 3 plen 使得ap1,ap2,ap3,aplen是乙個等差序列。輸入的第一行包含乙個整數t,表示組數。下接t組資料,每組第一行乙個整數n,每組第二行為乙個1到n的排列,數字兩兩之間用空格隔開。對於每組資料,如果存在乙個等差子串行,則輸出一行 y 否則輸出一行 n...