【題目描述 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 #include4using
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...