BZOJ 2124 (线段树 + hash)
题目链接:https://www.lydsy.com/JudgeOnline/problem.php?id=2124
题意:给一个1到N的排列{Ai},询问是否存在1<=p1<p2<p3<p4<p5<…<pLen<=N (Len>=3),使得Ap1,Ap2,Ap3,…ApLen是一个等差序列。
题解:显然若存在i < j < k,使得 aj - ai = ak - aj 则答案存在,考虑枚举 j ,判断是否存在 t 使得 aj - t 在 j 的左边且 aj + t 在 j 的右边。 对 n 个点建线段树,如果数 v 在 aj 的左边则线段树第 v 个叶子节点值为 1,否则为 0,枚举 j 的过程中进行单点修改,可以发现枚举到 j 的时候,若不存在长度为 3 的等差数列,则左边倒着和右边正着的 01 序列是完全相同的,故可以用哈希来维护一个区间正着和倒着的值,查询直接判断是否相等即可。(注意细节)
#include <bits/stdc++.h>
using namespace std;
#define ll long long
#define ull unsigned long long
#define mst(a,b) memset((a),(b),sizeof(a))
#define mp(a,b) make_pair(a,b)
#define pi acos(-1)
#define pii pair<int,int>
#define pb push_back
const int INF = 0x3f3f3f3f;
const double eps = 1e-;
const int MAXN = 1e4 + ;
const int MAXM = 1e3 + ;
const ll mod = 1e9 + ; int a[MAXN];
ll add[MAXN],hash1[MAXN<<],hash2[MAXN<<]; void pushup(int rt,int l,int r) {
int mid = (l + r) >> ;
hash1[rt] = (hash1[rt<<] * add[r - mid] + hash1[rt<<|]) % mod;
hash2[rt] = (hash2[rt<<|] * add[mid - l + ] + hash2[rt<<]) % mod;
} void update(int rt,int l,int r,int pos) {
if(l == r) {
hash1[rt] = hash2[rt] = ;
return ;
}
int mid = (l + r) >> ;
if(pos <= mid) update(rt<<,l,mid,pos);
else update(rt<<|,mid + ,r,pos);
pushup(rt,l,r);
} ll query1(int rt,int l,int r,int ql,int qr) {
if(ql > qr) return ;
if(ql == l && qr == r) return hash1[rt];
int mid = (l + r) >> ;
if(qr <= mid) return query1(rt<<,l,mid,ql,qr);
else if(ql > mid) return query1(rt<<|,mid + ,r,ql,qr);
else return (query1(rt<<,l,mid,ql,mid) * add[qr - mid] + query1(rt<<|,mid + ,r,mid + ,qr)) % mod;
} ll query2(int rt,int l,int r,int ql,int qr) {
if(ql > qr) return ;
if(ql == l && qr == r) return hash2[rt];
int mid = (l + r) >> ;
if(qr <= mid) return query2(rt<<,l,mid,ql,qr);
else if(ql > mid) return query2(rt<<|,mid + ,r,ql,qr);
else return (query2(rt<<|,mid + ,r,mid + ,qr) * add[mid - ql + ] + query2(rt<<,l,mid,ql,mid)) % mod;
} int main() {
#ifdef local
freopen("data.txt", "r", stdin);
// freopen("data.txt", "w", stdout);
#endif
add[] = ;
for(int i = ; i < MAXN; i++) add[i] = add[i - ] * (ll) % mod;
int t;
scanf("%d",&t);
while(t--) {
int n;
scanf("%d",&n);
for(int i = ; i <= n; i++) scanf("%d",&a[i]);
mst(hash1, );
mst(hash2, );
bool flag = false;
for(int i = ; i <= n; i++) {
int len = min(a[i] - , n - a[i]);
ll ans1 = query1(,,n,a[i] - len,a[i] - );
ll ans2 = query2(,,n,a[i] + ,a[i] + len);
if(ans1 != ans2) {
flag = true;
break;
}
update(,,n,a[i]);
}
if(flag) puts("Y");
else puts("N");
}
return ;
}
BZOJ 2124 (线段树 + hash)的更多相关文章
- BZOJ 2124 线段树维护hash值
思路: http://blog.csdn.net/wzq_QwQ/article/details/47152909 (代码也是抄的他的) 自己写得垃圾线段树怎么都过不了 隔了两个月 再写 再挂 又隔了 ...
- bzoj2124: 等差子序列线段树+hash
bzoj2124: 等差子序列线段树+hash 链接 https://www.lydsy.com/JudgeOnline/problem.php?id=2124 思路 找大于3的等差数列其实就是找等于 ...
- Codeforces Round #321 (Div. 2) E. Kefa and Watch 线段树hash
E. Kefa and Watch Time Limit: 1 Sec Memory Limit: 256 MB 题目连接 http://codeforces.com/contest/580/prob ...
- BZOJ_2124_等差子序列_线段树+Hash
BZOJ_2124_等差子序列_线段树+Hash Description 给一个1到N的排列{Ai},询问是否存在1<=p1<p2<p3<p4<p5<…<pL ...
- BZOJ 2124等差子序列 线段树&&hash
[题目描述 Description] 给一个 1 到 N 的排列{Ai},询问是否存在 1<=p1<p2<p3<p4<p5<…<pLen<=N(Len& ...
- bzoj 1645: [Usaco2007 Open]City Horizon 城市地平线【线段树+hash】
bzoj题面什么鬼啊-- 题目大意:有一个初始值均为0的数列,n次操作,每次将数列(ai,bi-1)这个区间中的数与ci取max,问n次后元素和 离散化,然后建立线段树,每次修改在区间上打max标记即 ...
- BZOJ2124:等差子序列(线段树,hash)
Description 给一个1到N的排列{Ai},询问是否存在1<=p1<p2<p3<p4<p5<…<pLen<=N (Len>=3), 使得A ...
- hdu 5172(线段树||HASH)
GTY's gay friends Time Limit: 6000/3000 MS (Java/Others) Memory Limit: 65536/65536 K (Java/Others ...
- CF452F等差子序列 & 线段树+hash查询区间是否为回文串
记录一下一个新学的线段树基础trick(真就小学生trick呗) 给你一个1到n的排列,你需要判断该排列内部是否存在一个3个元素的子序列(可以不连续),使得这个子序列是等差序列.\(n\) <= ...
随机推荐
- fcntl和flock两个系统调用的区别
总的来说,flock函数只能锁定整个文件,无法锁定文件的某一区域.而fcntl可以利用struct flock结构体,来实现文件里部分区域锁定的操作. 附:fcntl(文件描述词操作) 相关函数 op ...
- 使用kubeadm进行单master(single master)和高可用(HA)kubernetes集群部署
kubeadm部署k8s 使用kubeadm进行k8s的部署主要分为以下几个步骤: 环境预装: 主要安装docker.kubeadm等相关工具. 集群部署: 集群部署分为single master(单 ...
- [转]史上最最最详细的手写Promise教程
我们工作中免不了运用promise用来解决异步回调问题.平时用的很多库或者插件都运用了promise 例如axios.fetch等等.但是你知道promise是咋写出来的呢? 别怕-这里有本promi ...
- Python实现二叉树的非递归先序遍历
思路: 1. 使用列表保存结果: 2. 使用栈(列表实现)存储结点: 3. 当根结点存在,保存结果,根结点入栈: 4. 将根结点指向左子树: 5. 根结点不存在,栈顶元素出栈,并将根结点指向栈顶元素的 ...
- work note
eclipse git 察看历史 左边是提交的 import { NgModule } from '@angular/core'; import { IonicPageModule } from 'i ...
- python之并发编程(概念篇)
一.进程 1.什么是进程 进程是正在进行的一个过程或者一个任务.而负责执行任务的则是cpu. 2.进程与程序的区别 程序并不能单独运行,只有将程序装载到内存中,系统为它分配资源才能运行,而这种执行的程 ...
- 第十章 MIZ702 ZYNQ制作UBOOT固化程序
10.0难度系数★☆☆☆☆☆☆ 10.1是什么是固化 我们前几章将的程序都是通过JTAG先下载bit流文件,再下载elf文件,之后点击Run As来运行的程序.JTAG的方法是通过TCL脚本来初始化P ...
- JWT与Session比较和作用
1. JSON Web Token是什么 JSON Web Token (JWT)是一个开放标准(RFC 7519),它定义了一种紧凑的.自包含的方式,用于作为JSON对象在各方之间安全地传输信息.该 ...
- SWATS算法剖析(自动切换adam与sgd)
SWATS算法剖析(自动切换adam与sgd) 战歌指挥官 搬砖.码砖.代查水表.... 27 人赞同了该文章 SWATS是ICLR在2018的高分论文,提出的一种自动由Adam切换为SGD而实现更好 ...
- c# 将datatable中的数据保存到excel文件中
using System; using System.Collections.Generic; using System.Data; using System.IO; using System.Lin ...