我又来更博啦
 
 

2124: 等差子序列

Time Limit: 3 Sec  Memory Limit: 259 MB
Submit: 941  Solved: 348
[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

 
 
 时隔多年两个月我终于想起来更博辣
(早就AC的神犇们请轻喷)
 
 分析题意:既然长度大于等于3,那我们找长为3的等差子序列就好了
大暴力:枚举这三项的位置l,mid,r O(n^3)
这也太暴力了,所以想办法优化一下
枚举等差中项,每次O(n)扫一遍左右两部分,用哈希判断是否右区间出现了满足与中点和左区间的一个配对的元素
意思是01序列维护枚举中项的过程中左区间出现了的数,很方便判断是否满足条件 
O(n^2)
再考虑题目特殊之处:1到n的排列,每个数一定且仅出现一次
那么我们想,一个数之前只出现了比它自身小的数,而排列又一定出现比它大的数
之前出现比它大的数也同理 
而对于一个给定的数 i ,满足条件数是:i-1,i+1  i-2,i+2 ...
要找的数在数轴上沿 i 对称
所以我们找到一个数,不用管它之后出现了哪些数,
开一个记录之前出现过的数的01数组
那么判断这个数组是否存在以这个数i为回文中心的回文子串就够了(想一想,)
有人说manacher,但是回去看题
没有回文串,即一定存在一个等差子序列我们直接就可以回答了(此处坑,稍后讲)
判断是否不存在一个回文子串好说
直接看当前数向两边最大扩展相同长度的子串是否为回文串就够了 
比如对于排列  1 3 2
首先  0 0 0
发现以1为中心的最长子串长为1,是回文子串
把1加进来   1 0 0
3同理   1 0 1
处理2 发现以2为中心的最长子串长为3,是回文子串
以各个数为中心的子串均为回文子串,不存在等差子序列
可是还有一点
我们的复杂度依然是平方的
考虑优化
(这里直接把01串当成字符串好了) 
对于判断回文串,我们可以把字符串hash进来,O(1)地判断左边右边两个子串是否相等
具体说就是维护正向和反向两个字符串哈希,快速查左右两个子串(阅读方向不同)是否相等 
但对哈希值的询问和修改都是动态的 
使用树状数组维护
(所以这一点才是最重要的好吗!!!!!!!!!!!用树状数组维护这种根本算不上区间减法的东西真的合适吗喂喂喂!!!!!)
首先预处理一个2(比2大也行)的几次幂数组,模一个大素数(又是坑,放到后面提)
在维护树状数组时,不能简单地加起来,而要把靠前的区间的值右移至与后面的区间补齐(可别直接<<啊),幂数组就派上用场了
此题蜜汁WA到死,过了之后得出一个惨痛教训:既然已经模了一个素数,就不要unsinged了就不要unsinged了就不要unsinged了就不要unsinged了
到底为什么我也不太清楚
好了隔这么久更博才忍不住多说点,上代码

 #include<stdio.h>
#include<stdlib.h>
#include<string.h>
#define LL long long //别开unsigned
const LL mod=(LL)1e9+; //非洲人老老实实去找别人家的素数
int n;
LL pw[];
LL bit1[],bit2[];
int a[];
/*int binpr(int x){
int sta[10]={0},top=0;
while(x){
top++;
if(x&1)sta[top]=1;
}
++top;
while(--top){
printf("%d",sta[top]);
}
return 0;
}*/
int min(int a,int b){
return a<b?a:b;
}
int lb(int x){
return x&(-x);
}
LL q1(int x){
LL ans=;
int i=x;
while(i){
ans=(ans+(bit1[i]*pw[x-i])%mod)%mod;
i-=lb(i);
}
return ans;
}
LL q2(int x){
LL ans=;
int i=x;
while(i){
ans=(ans+(bit2[i]*pw[x-i])%mod)%mod;
i-=lb(i);
}
return ans;
}
LL c1(int x){
int i=x;
while(i<=n){
bit1[i]=(bit1[i]+pw[i-x])%mod;
i+=lb(i);
}
return ;
}
LL c2(int x){
int i=x;
while(i<=n){
bit2[i]=(bit2[i]+pw[i-x])%mod;
i+=lb(i);
}
return ;
}
LL qr1(int l,int r){
LL p=q1(l-),q=q1(r);
return ((q-p*pw[r-l+])%mod+mod)%mod;
}
LL qr2(int l,int r){
LL p=q2(l-),q=q2(r);
return ((q-p*pw[r-l+])%mod+mod)%mod;
}
int main(){
int t;
scanf("%d",&t);
pw[]=;
for(int i=;i<=;i++)pw[i]=(pw[i-]*(LL))%mod;
while(t--){
scanf("%d",&n);
for(int i=;i<=n;i++)scanf("%d",&a[i]);//坑点:按照这种算法以为是在线,BUT!多组数据!千万别在线做得出解就立马跳出!最起码先读进来
memset(bit1,,sizeof(bit1));
memset(bit2,,sizeof(bit2));
int note=;
for(int i=;i<=n;i++){
int x=a[i];
int len=min(n-x,x-);
if(len && qr1(x-len,x-)!=qr2(n-x-len+,n-x)){
note=;
puts("Y");
break;
}
c1(x);
c2(n-x+);
}
if(!note)puts("N");
}
return ;
}

后记:

06年的渣机在编辑这篇题解时蓝屏一次,死机重开(未保存)五次,卡住重开(未保存)不计其数

凭借着无限的毅力更新完毕这篇久违的题解

再立个flag:我也要当更博狂魔!

 

[bzoj2124]等差子序列(hash+树状数组)的更多相关文章

  1. bzoj2124 等差子序列(树状数组+hash)

    题意 给你一个1~n排列,问有没有一个等差数列(长度至少为3) 题解 我居然自己想到了正解. 但我最后写挂了,所以我又看了题解. 我们维护了一个以权值为下标的01序列. 我们扫描整个序列.对于每一个正 ...

  2. BZOJ2124 等差子序列(树状数组+哈希)

    容易想到一种暴力的做法:枚举中间的位置,设该位置权值为x,如果其两边存在权值关于x对称即合法. 问题是如何快速寻找这个东西是否存在.考虑仅将该位置左边出现的权值标1.那么若在值域上若关于x对称的两权值 ...

  3. BZOJ2124: 等差子序列(树状数组&hash -> bitset 求是否存在长度为3的等差数列)

    2124: 等差子序列 Time Limit: 3 Sec  Memory Limit: 259 MBSubmit: 2354  Solved: 826[Submit][Status][Discuss ...

  4. bzoj2124: 等差子序列线段树+hash

    bzoj2124: 等差子序列线段树+hash 链接 https://www.lydsy.com/JudgeOnline/problem.php?id=2124 思路 找大于3的等差数列其实就是找等于 ...

  5. acdream1197 Points In Cuboid(hash树状数组)

    题目链接:http://acdream.info/problem?pid=1197 题意:给出三维空间n个点,m个查询,每次查询某个立方体内的点的个数. 思路:按照一维排序,根据查询插入,其他两位用二 ...

  6. URAL-1989 Subpalindromes 多项式Hash+树状数组

    题目链接:http://acm.timus.ru/problem.aspx?space=1&num=1989 题意:给出一个字符串,m个操作:1,修改其中一个字符串,2,询问 [a, b] 是 ...

  7. [poj 1533]最长上升子序列nlogn树状数组

    题目链接:http://poj.org/problem?id=2533 其实这个题的数据范围n^2都可以过,只是为了练习一下nlogn的写法. 最长上升子序列的nlogn写法有两种,一种是变形的dp, ...

  8. P7114 [NOIP2020] 字符串匹配 (字符串hash+树状数组)

    好多题解用的扩展KMP(没学过,所以不用这种方法). 我们按照题目要求记F(s)表示s串的权值,可以预处理出前缀权值(用于A)和后缀权值(用于C),枚举AB的长度i=2~n-1,不需要分开枚举,我们只 ...

  9. 【BZOJ】3173: [Tjoi2013]最长上升子序列(树状数组)

    [题意]给定ai,将1~n从小到大插入到第ai个数字之后,求每次插入后的LIS长度. [算法]树状数组||平衡树 [题解] 这是树状数组的一个用法:O(n log n)寻找前缀和为k的最小位置.(当数 ...

随机推荐

  1. jquery动态刷新select的值,后台传过来List<T>,前台解析后填充到select的option中

    jquery动态刷新select的值:将后台传来的List<T>赋值到select下的option. 第一个select选择后出发该方法refreshMerchant(params),传递 ...

  2. hibernate学习(2)——api详解对象

    1   Configuration 配置对象 /详解Configuration对象 public class Configuration_test { @Test //Configuration 用户 ...

  3. perl基础

    perl比较好的博客:http://www.cnblogs.com/cosiray/archive/2012/03/18/2404371.html 以分析一个简单的pm文件为例 # # オプションの取 ...

  4. java程序中调用Linux命令Windows命令

    目前总结的方法: 调用Linux简单的命令行,设置文件夹权限755 String scriptDir = "/home/wenf"; String cmd = "chmo ...

  5. 捕获Insert触发器失败记录

    1.背景 环境:发布服务器A Windows2008+SQL2008,分发服务器B Windows2008+SQL2008,订阅服务器C Windows2008+SQL2012发布服务器A上的用户信息 ...

  6. ios-高仿别踩白块游戏的实现

    先看下效果图片 前几天看到一个游戏叫别踩白块,下载量还挺大几百万了都,下载下来玩了玩看了看,这个游戏还挺简单的.俗话说想一千遍,一万遍不如动手做一遍来的实在.昨晚以及今天白天闲的没事就开搞了,下午六点 ...

  7. 【java开发系列】—— spring简单入门示例

    1 JDK安装 2 Struts2简单入门示例 前言 作为入门级的记录帖,没有过多的技术含量,简单的搭建配置框架而已.这次讲到spring,这个应该是SSH中的重量级框架,它主要包含两个内容:控制反转 ...

  8. C# 中using的几个用途

    参考文献 http://www.cnblogs.com/morningwang/archive/2008/03/12/1102952.html http://msdn.microsoft.com/zh ...

  9. ajax+jquery+ashx如何实现上传文件

    第一:建立Default.aspx页面 <html> <head runat="server"> <title>ajax图片上传</tit ...

  10. HDU 4770 Lights Against DudelyLights

    Lights Against Dudely Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Ot ...