首页 > 其他 > 详细

BZOJ 2124: 等差子序列

时间:2017-01-09 18:22:56      阅读:156      评论:0      收藏:0      [点我收藏+]

2124: 等差子序列

Time Limit: 3 Sec  Memory Limit: 259 MB
Submit: 1041  Solved: 376
[Submit][Status][Discuss]

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

Source

分析:

我们只需要判断是否存在一个长度为3的等差子序列就好...

首先我们有一个很机智的想法...我们枚举中间的数x,判断是否存在x-y和x+y分别在x两边...我们从左向右扫描当前数字记为中间数字,维护一个vis数组,vis[i]=1代表i在当前数字之前出现过,=0代表没有出现过...然后只要当前数字的左右两边的01串不一样就代表存在一组合法解...

这种判断回文串的问题可以通过hash解决,但是我们要动态维护hash值,所以要借助树状数组或者线段树...

记得一定要开long long...

代码:

技术分享
 1 #include<algorithm>
 2 #include<iostream>
 3 #include<cstring>
 4 #include<cstdio>
 5 //by NeighThorn
 6 #define int long long
 7 using namespace std;
 8 
 9 const int maxn=10000+5,Mod=1e9+7;
10 
11 int n,cas,flag,p[maxn];
12 
13 struct Tree{
14     
15     long long tr[maxn];
16     
17     inline void clear(void){
18         memset(tr,0,sizeof(tr));
19     }
20     
21     inline void insert(int x,int y){
22         int lala=x;
23         for(;x<=n;x+=x&-x)
24             (tr[x]+=y*p[x-lala])%=Mod;
25     }
26     
27     inline int query(int x){
28         int lala=x,res=0;
29         for(;x;x-=x&-x)
30             (res+=((long long)tr[x]*p[lala-x])%Mod)%Mod;
31         return res;
32     }
33     
34     inline int qry(int l,int r){
35         return ((long long)query(r)-(long long)query(l-1)*p[r-l+1]%Mod+Mod)%Mod;
36     }
37     
38 }a,b;
39 
40 signed main(void){
41     scanf("%lld",&cas);p[0]=1;
42     for(int i=1;i<=10000;i++)
43         p[i]=(p[i-1]<<1)%Mod;
44     while(cas--){
45         scanf("%lld",&n);flag=0;
46         a.clear();b.clear();
47         for(int i=1,x;i<=n;i++){
48             scanf("%lld",&x);
49             if(flag)
50                 continue;
51             int lala=min(x-1,n-x);
52             if(lala&&a.qry(x-lala,x-1)!=b.qry(n-(x+lala)+1,n-(x+1)+1))
53                 puts("Y"),flag=1;
54             a.insert(x,1),b.insert(n-x+1,1);
55         }
56         if(!flag)
57             puts("N");
58     }
59     return 0;    
60 }
View Code

By NeighThorn

BZOJ 2124: 等差子序列

原文:http://www.cnblogs.com/neighthorn/p/6265737.html

(0)
(0)
   
举报
评论 一句话评论(0
关于我们 - 联系我们 - 留言反馈 - 联系我们:wmxa8@hotmail.com
© 2014 bubuko.com 版权所有
打开技术之扣,分享程序人生!