bzoj 2124: 等差子序列 (线段树+hash)
来源:互联网 发布:sql查询平均分大于60 编辑:程序博客网 时间:2024/06/06 14:20
题目描述
传送门
题目大意: 给出1…n的一个排列,问序列中是否存在一个长度>=3的等差数列
题解
这道题解题的关键就是给出的序列是1..n的一个排列。
根据等差数列的性质:等差数列 x,y,z 满足2*y=x+z,那么我们如果转换成位置关系的话,在数轴上x,z是关于y对称的。
那么对于每个y,什么时候才能形成等差数列呢?关于他对称的所有数对中存在一对数在序列中的顺序一个在他之前一个在他之后
那么我们可以建立一颗权值线段树,按照序列中的顺序依次插入a[i],如果[a[i]-len,a[i]-1]的hash值与[a[i]+len,a[i]+1]的hash值相同,那么一定不存在合法的数对。
代码
#include<iostream>#include<cstdio>#include<cstring>#include<algorithm>#include<cmath>#define N 10003#define p 2000001001#define ull unsigned long long using namespace std;ull mi[N],tr[N*4],tr1[N*4];int a[N],T,n;ull update(ull x,ull y,int len){ return x*mi[len]+y;}void build(int now,int l,int r){ tr[now]=tr1[now]=0; if (l==r) return; int mid=(l+r)/2; build(now<<1,l,mid); build(now<<1|1,mid+1,r);}void pointchange(int now,int l,int r,int x){ if (l==r) { tr[now]=1; tr1[now]=1; return; } int mid=(l+r)/2; if (x<=mid) pointchange(now<<1,l,mid,x); else pointchange(now<<1|1,mid+1,r,x); tr[now]=update(tr[now<<1],tr[now<<1|1],r-mid); tr1[now]=update(tr1[now<<1|1],tr1[now<<1],mid-l+1);}ull find(int now,int l,int r,int ll,int rr){ if (ll>rr) return 0; if (ll<=l&&r<=rr) return tr[now]; int mid=(l+r)/2; ull ans=0; int len=0; if (ll<=mid) ans=update(ans,find(now<<1,l,mid,ll,rr),len),len=min(r,rr)-mid; if (rr>mid) ans=update(ans,find(now<<1|1,mid+1,r,ll,rr),len); return ans;}ull find1(int now,int l,int r,int ll,int rr){ if (ll>rr) return 0; if (ll<=l&&r<=rr) return tr1[now]; int mid=(l+r)/2; ull ans=0; int len=0; if (ll<=mid) ans=update(find1(now<<1,l,mid,ll,rr),ans,len),len=mid-max(l,ll)+1; if (rr>mid) ans=update(find1(now<<1|1,mid+1,r,ll,rr),ans,len); return ans;}int main(){ freopen("a.in","r",stdin); freopen("my.out","w",stdout); scanf("%d",&T); mi[0]=1; for (int i=1;i<=10000;i++) mi[i]=mi[i-1]*p; while (T--) { scanf("%d",&n); for (int i=1;i<=n;i++) scanf("%d",&a[i]); build(1,1,n); int mid=n/2; if (n&1) mid++; bool pd=false; for (int i=1;i<=n;i++) { ull x,y; int t; if (a[i]<=mid) { t=a[i]-1; x=find(1,1,n,1,a[i]-1); y=find1(1,1,n,a[i]+1,a[i]+t); //cout<<x<<" "<<y<<endl; if (x!=y) pd=true; } else { t=n-a[i]; x=find(1,1,n,a[i]-t,a[i]-1); y=find1(1,1,n,a[i]+1,n); //cout<<x<<" "<<y<<endl; if (x!=y) pd=true; } pointchange(1,1,n,a[i]); } if (pd) printf("Y\n"); else printf("N\n"); }}
0 0
- bzoj 2124: 等差子序列 (线段树+hash)
- BZOJ 2124 等差子序列 线段树维护hash值
- 2124: 等差子序列 线段树+hash
- BZOJ 2124 等差子序列 (树状数组 hash)
- bzoj2124 等差子序列(hash+线段树)
- bzoj 2124: 等差子序列 树状数组&hash
- [BZOJ]2124 等差子序列 Hash&树状数组
- BZOJ 2124: 等差子序列 [树状数组][hash]
- 【bzoj2124】等差子序列 权值线段树维护hash
- BZOJ 2124 等差子序列
- BZOJ 2124: 等差子序列
- [BZOJ 2124] 等差子序列 Hash+树状数组(附粗略证明)
- [线段树] [Hash] [BZOJ2124] 等差子数列
- 2124: 等差子序列|线段树维护哈希值
- 2124: 等差子序列
- bzoj2124 等差子序列 (树状数组 维护hash值)
- 最长等差子序列
- codevs1283等差子序列
- 用两个栈实现队列
- CSS——CSS入门语法
- unix系统之进程初始化
- Mysql数据库
- UVa_Andy's First Dictionary(Set)
- bzoj 2124: 等差子序列 (线段树+hash)
- 动态初始化checkBox复选框及修改时赋值
- 成员初始化列表
- Log4j配置小记
- SimpleAdapter创建ListView
- http请求不占用并发资源的同步操作
- SQL面试总结
- How to Add An Automatically Executable Program in YOCTO?
- idcnd传媒-稳定的加群服务