2124: 等差子序列 - BZOJ

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

 

转载于:https://www.cnblogs.com/Randolph87/p/3742670.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值