Description
给一个1到N的排列{Ai},询问是否存在1<=p1=3),使得Ap1,Ap2,Ap3,…ApLen是一个等差序列。
Input
输入的第一行包含一个整数T,表示组数。下接T组数据,每组第一行一个整数N,每组第二行为一个1到N的排列,数字两两之间用空格隔开。
Output
对于每组数据,如果存在一个等差子序列,则输出一行“Y”,否则输出一行“N”。
Sample Input
2
3
1 3 2
3
3 2 1
Sample Output
N
Y
HINT
对于100%的数据,N<=10000,T<=7
首先觉得题目不错(2013年我竟然在wikioi过了,代码还很短,然后把代码翻出来,发现是暴力n方加优化代码。。。。。。汗,我当时怎么想的)
今天看到题目觉得没什么想法,于是就翻了题解http://seter.is-programmer.com/posts/31902.html
就是维护每一个数字a[i]之前出现a[i]-1,a[i]-2,a[i]-3...的出现情况和a[i]+1,a[i]+2,a[i]+3...的出现情况(用二进制)
如果这两个二进制数的第k位不同,那么就是a[i]-k在a[i]前出现了,a[i]+k在a[i]之后出现或者a[i]+k在a[i]前出现了,a[i]-k在a[i]之后出现,所以我们只要判断两个二进制不同,就可以用hash值来判断了(不放心的话可以做两个hash),用线段树维护hash值就行了
1 const
2 maxn=10010;
3 h=1000000007;
4 type
5 node=record
6 l,r,lc,rc:longint;
7 h1,h2:int64;
8 end;
9 var
10 f:array[0..maxn*2]of node;
11 a:array[0..maxn]of longint;
12 p:array[0..maxn]of int64;
13 t,n,tot:longint;
14
15 function min(x,y:longint):longint;
16 begin
17 if x<y then exit(x);
18 exit(y);
19 end;
20
21 function max(x,y:longint):longint;
22 begin
23 if x>y then exit(x);
24 exit(y);
25 end;
26
27 procedure add(x,now:longint);
28 var
29 mid:longint;
30 begin
31 if f[now].l=f[now].r then
32 begin
33 f[now].h1:=1;
34 f[now].h2:=1;
35 exit;
36 end;
37 mid:=(f[now].l+f[now].r)>>1;
38 if x>mid then add(x,f[now].rc)
39 else add(x,f[now].lc);
40 f[now].h1:=(f[f[now].lc].h1*p[f[now].r-mid]+f[f[now].rc].h1)mod h;
41 f[now].h2:=(f[f[now].rc].h2*p[mid-f[now].l+1]+f[f[now].lc].h2)mod h;
42 end;
43
44 procedure build(l,r:longint);
45 var
46 now,mid:longint;
47 begin
48 inc(tot);
49 now:=tot;
50 f[now].l:=l;
51 f[now].r:=r;
52 f[now].h1:=0;
53 f[now].h2:=0;
54 f[now].lc:=0;
55 f[now].rc:=0;
56 if l=r then exit;
57 mid:=(l+r)>>1;
58 f[now].lc:=tot+1;
59 build(l,mid);
60 f[now].rc:=tot+1;
61 build(mid+1,r);
62 end;
63
64 function hash1(l,r,now:longint):int64;
65 var
66 mid:longint;
67 begin
68 if (l<=f[now].l) and (r>=f[now].r) then exit(f[now].h1);
69 mid:=(f[now].l+f[now].r)>>1;
70 if l>mid then exit(hash1(l,r,f[now].rc));
71 if r<=mid then exit(hash1(l,r,f[now].lc));
72 exit((hash1(l,r,f[now].lc)*p[min(r,f[now].r)-mid]+hash1(l,r,f[now].rc))mod h);
73 end;
74
75 function hash2(l,r,now:longint):int64;
76 var
77 mid:longint;
78 begin
79 if (l<=f[now].l) and (r>=f[now].r) then exit(f[now].h2);
80 mid:=(f[now].l+f[now].r)>>1;
81 if l>mid then exit(hash2(l,r,f[now].rc));
82 if r<=mid then exit(hash2(l,r,f[now].lc));
83 exit((hash2(l,r,f[now].rc)*p[mid-max(l,f[now].l)+1]+hash2(l,r,f[now].lc))mod h);
84 end;
85
86 procedure main;
87 var
88 i:longint;
89 begin
90 read(n);
91 for i:=1 to n do
92 read(a[i]);
93 tot:=0;
94 build(1,n);
95 for i:=2 to n-1 do
96 begin
97 add(a[i-1],1);
98 if hash1(a[i]-min(a[i]-1,n-a[i]),a[i],1)=hash2(a[i],a[i]+min(a[i]-1,n-a[i]),1) then continue;
99 writeln(‘Y‘);
100 exit;
101 end;
102 writeln(‘N‘);
103 end;
104
105 begin
106 p[0]:=1;
107 for t:=1 to maxn do
108 p[t]:=p[t-1]*2 mod h;
109 read(t);
110 while t>0 do
111 begin
112 dec(t);
113 main;
114 end;
115 end.
View
Code
2124: 等差子序列 - BZOJ,布布扣,bubuko.com
时间: 2024-10-05 04:40:48