线段树维护哈希值

要求出现长度大于三的等差子序列,我们只要找到长度等于三的就可以了

初看本题没有思路,只能暴力枚举,O(n^4)

后来发现,这个序列是n的一个排列,那么每个数字都只会出现一次

我们可以维护一个 \(01\) 序列 B ,表示某个数字是否出现过,

然后我们从左往右枚举等差中项x并将该项在B中置为1,存在等差数列当且仅当,

B序列以x为中心的极大子区间不是回文子区间

我们该如何高效的判断回文子区间呢,首先维护B的正反两个序列

然后有两种做法

1.线段树维护 \(01\) 序列的哈希值,要注意预处理,以及具体在某步中移多少位

2.用bitset维护

线段树维护哈希值,64位自然溢出

  1. #include <iostream>
  2. #include <cstdio>
  3. #include <cstring>
  4. #include <algorithm>
  5. #include <cstdlib>
  6. #include <cmath>
  7. #define lson l, mid, rt<<1
  8. #define rson mid + 1, r, rt<<1|1
  9. #define ll unsigned long long
  10. using namespace std;
  11. const int MAXN = 10005, base = 233;
  12. int init() {
  13. int rv = 0, fh = 1;
  14. char c = getchar ();
  15. while(c < '0' || c > '9') {
  16. if(c == '-') fh = -1;
  17. c = getchar();
  18. }
  19. while(c >= '0' && c <= '9') {
  20. rv = (rv<<1) + (rv<<3) + c - '0';
  21. c = getchar();
  22. }
  23. return fh * rv;
  24. }
  25. int T, n;
  26. ll hash1[MAXN<<2], hash2[MAXN<<2], idx[MAXN<<2];
  27. ll Query1(int L, int R, int l, int r,int rt) {
  28. if(L > R) return 0;
  29. if(L <= l && r <= R) {
  30. return hash1[rt];
  31. }
  32. int mid = (l + r) >>1;
  33. ll ans = 0;
  34. if(L <= mid) ans = Query1(L, R, lson);
  35. if(mid < R) {
  36. ans *= idx[min(R, r) - mid]; //注意min(R,r)
  37. ans += Query1(L, R, rson);
  38. }
  39. return ans;
  40. }
  41. ll Query2(int L, int R, int l, int r, int rt) {
  42. if(L > R) return 0;
  43. if(L <= l && r <= R) {
  44. return hash2[rt];
  45. }
  46. int mid = (l + r) >>1;
  47. ll ans = 0;
  48. if(mid < R) ans = Query2(L ,R, rson);
  49. if(L <= mid){
  50. ans *= idx[mid - max(L, l) + 1];
  51. ans += Query2(L, R, lson);
  52. }
  53. return ans;
  54. }
  55. void PushUp(int rt, int m) {
  56. hash1[rt] = hash1[rt<<1] * idx[m>>1] + hash1[rt<<1|1];
  57. hash2[rt] = hash2[rt<<1|1] * idx[m - (m>>1)] + hash2[rt<<1];
  58. }
  59. void Update(int x, int l, int r, int rt) {
  60. if(l >= r) {
  61. hash1[rt] = hash2[rt] = 1;
  62. return;
  63. }
  64. int mid = (l + r) >>1;
  65. if(x <= mid) Update(x, lson);
  66. else Update(x, rson);
  67. PushUp(rt, r - l + 1);
  68. }
  69. int main() {
  70. freopen("in.txt", "r", stdin);
  71. T = init();
  72. idx[0] = 1;
  73. for(int i = 1 ; i <= MAXN ; i++) {
  74. idx[i] = idx[i-1] * base;
  75. }
  76. while(T--) {
  77. n = init();
  78. memset(hash1, 0, sizeof(hash1));
  79. memset(hash2, 0, sizeof(hash2));
  80. bool f = 0;
  81. for(int i = 1 ; i <= n ; i++) {
  82. int x = init();
  83. int len = min(x - 1, n - x);
  84. if((!f) && (Query1(x - len, x - 1, 1, n, 1) != Query2(x + 1, x + len, 1, n, 1))) {
  85. f = 1;
  86. }
  87. Update(x, 1, n, 1);
  88. }
  89. printf("%c\n", f?'Y':'N');
  90. }
  91. fclose(stdin);
  92. return 0;
  93. }

BZOJ [P2124] 等差子序列的更多相关文章

  1. BZOJ 2124: 等差子序列

    Sol 线段树+Hash. 首先暴力 等差子序列至少3项就可以了,就枚举中项,枚举公差就可以了,只需要一个数在中项前出现,另一个数在中项前没出现过就可以了.复杂度 \(O(n^2)\) 然后我想了一个 ...

  2. BZOJ 2124等差子序列 线段树&&hash

    [题目描述 Description] 给一个 1 到 N 的排列{Ai},询问是否存在 1<=p1<p2<p3<p4<p5<…<pLen<=N(Len& ...

  3. bzoj 2124 等差子序列 (线段树维护hash)

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

  4. bzoj 2124 等差子序列 树状数组维护hash+回文串

    等差子序列 Time Limit: 3 Sec  Memory Limit: 259 MBSubmit: 1919  Solved: 713[Submit][Status][Discuss] Desc ...

  5. BZOJ 2124: 等差子序列 线段树维护hash

    2124: 等差子序列 Description 给一个1到N的排列{Ai},询问是否存在1<=p1=3),使得Ap1,Ap2,Ap3,…ApLen是一个等差序列. Input 输入的第一行包含一 ...

  6. 2124: 等差子序列 - BZOJ

    Description 给一个1到N的排列{Ai},询问是否存在1<=p1=3),使得Ap1,Ap2,Ap3,…ApLen是一个等差序列. Input 输入的第一行包含一个整数T,表示组数.下接 ...

  7. [BZOJ2124]等差子序列/[CF452F]Permutation

    [BZOJ2124]等差子序列/[CF452F]Permutation 题目大意: 一个\(1\sim n\)的排列\(A_{1\sim n}\),询问是否存在\(i,j(i<j)\),使得\( ...

  8. [bzoj2124]等差子序列(hash+树状数组)

    我又来更博啦     2124: 等差子序列 Time Limit: 3 Sec  Memory Limit: 259 MBSubmit: 941  Solved: 348[Submit][Statu ...

  9. bzoj2124 等差子序列(hash+线段树)

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

随机推荐

  1. 迅为10.1寸人机界面工业HMI安卓电容屏定制生产供应商

    10.1寸人机界面介绍: 配置铁电存储器:非易失性记忆体,掉电后数据不丢失. 连接云端,支持云服务:数据综合管理,更有效率. 静电防护技术:高强度抗干扰,防静电,防电磁干扰. 提供所有接口的调用源码, ...

  2. C++类构造函数、析构函数运行机理

    http://blog.sina.com.cn/s/blog_6fd68d5f0100n60h.html 前言--构造函数.析构函数的简单理解:1)构造函数---对象被创建时候调用的函数:2)析构函数 ...

  3. 1.JOIN和UNION区别

    1.JOIN和UNION区别join 是两张表做交连后里面条件相同的部分记录产生一个记录集,union是产生的两个记录集(字段要一样的)并在一起,成为一个新的记录集 . JOIN用于按照ON条件联接两 ...

  4. 使用vue做移动端瀑布流分页

    讲到瀑布流分页有一个方法一定是要用到的 pullToRefresh() 这个也没什么好解释的,想了解的可以去百度一下 下面上代码 <div id="main" class=& ...

  5. C++函数调用过程深入分析<转>

    转自http://blog.csdn.net/dongtingzhizi/article/details/6680050 C++函数调用过程深入分析 作者:靠谱哥 微博:洞庭之子-Bing 0. 引言 ...

  6. MySQL数据库安全配置

    文章来源:http://www.xfocus.net MySQL数据库安全配置 1.前言 MySQL 是完全网络化的跨平台关系型数据库系统,同时是具有客户机/服务器体系结构的分布式数据库管理系统.它具 ...

  7. Bootstrap历练实例:基本按钮组

    <!DOCTYPE html><html><head><meta http-equiv="Content-Type" content=&q ...

  8. 基于Passthru的NDIS开发的个人理解

    这几天对NDIS的学习,基本思路是:首先熟悉理论知识→然后下载一个例子进行研究→最后例子自己模仿扩展→最最后尝试自己写一个新的. Passthru是微软NDIS自己写的一个框架驱动,NDIS开发者可以 ...

  9. POJ 3080 Blue Jeans、POJ 3461 Oulipo——KMP应用

    题目:POJ3080 http://poj.org/problem?id=3080 题意:对于输入的文本串,输出最长的公共子串,如果长度相同,输出字典序最小的. 这题数据量很小,用暴力也是16ms,用 ...

  10. Git学习之路

    目录 git安装 linux windows git命令 创建版本库 提交文件 仓库状态 版本回退 工作区和暂存区 工作区 暂存区 推送.下拉和克隆 推送 下拉 克隆 git应该可以说是程序员必备技能 ...