BZOJ P2124 等差子串行

2022-05-10 05:56:52 字數 1519 閱讀 3791

要求出現長度大於三的等差子串行,我們只要找到長度等於三的就可以了

初看本題沒有思路,只能暴力列舉,o(n^4)

後來發現,這個序列是n的乙個排列,那麼每個數字都只會出現一次

我們可以維護乙個 \(01\) 序列 b ,表示某個數字是否出現過,

然後我們從左往右列舉等差中項x並將該項在b中置為1,存在等差數列當且僅當,

b序列以x為中心的極大子區間不是回文子區間

我們該如何高效的判斷回文子區間呢,首先維護b的正反兩個序列

然後有兩種做法

1.線段樹維護 \(01\) 序列的雜湊值,要注意預處理,以及具體在某步中移多少位

2.用bitset維護

線段樹維護雜湊值,64位自然溢位

#include #include #include #include #include #include #define lson l, mid, rt<<1

#define rson mid + 1, r, rt<<1|1

#define ll unsigned long long

using namespace std;

const int maxn = 10005, base = 233;

int init()

while(c >= '0' && c <= '9')

return fh * rv;

}int t, n;

ll hash1[maxn<<2], hash2[maxn<<2], idx[maxn<<2];

ll query1(int l, int r, int l, int r,int rt)

int mid = (l + r) >>1;

ll ans = 0;

if(l <= mid) ans = query1(l, r, lson);

if(mid < r)

return ans;

}ll query2(int l, int r, int l, int r, int rt)

int mid = (l + r) >>1;

ll ans = 0;

if(mid < r) ans = query2(l ,r, rson);

if(l <= mid)

return ans;

}void pushup(int rt, int m)

void update(int x, int l, int r, int rt)

int mid = (l + r) >>1;

if(x <= mid) update(x, lson);

else update(x, rson);

pushup(rt, r - l + 1);

}int main()

while(t--)

update(x, 1, n, 1);

} printf("%c\n", f?'y':'n');

} fclose(stdin);

return 0;

}

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...