Description

S也想寻求真正的智慧,然而由于“抑制力”的存在,她必须先解决一系列询
问。
有一个长度为n的序列a,一个长度为m序列b被称为螺旋序列当且仅当
b1=bm且对于1<=i<=m有bi<=b1。
S需要回答q个询问,每个询问用l,r两个参数描述,表示询问区间[l,r]的最长
连续子螺旋序列的长度。

Input

第一行两个整数n,q,表示序列长度和询问数。
第二行n个整数ai表示序列a。
以下q行,每行两个整数l,r表示一次询问。

Output

对每次询问输出一行一个整数表示最大连续螺旋序列的长度。

Sample Input

5 3
3 2 1 2 3
1 4
2 5
1 5

Sample Output

3
3
5

Data Constraint

本题采用捆绑测试,只有通过一个子任务的全部数据才能得到该子任务分
数,否则不得分。
子任务1(20分):n,m<=10
子任务2(20分):n,m<=1000
子任务3(20分):n,m<=2*10^5,1<=ai<=10
子任务4(40分):n,m<=5*10^5;|ai|<=10^9

Solution

30分的裸暴力

离散化相等的数字,做一个链表,st表处理区间最大值,对每个询问都暴力去跳

  1. #include <map>
  2. #include <vector>
  3. #include <stdio.h>
  4. #include <string.h>
  5. #include <algorithm>
  6. #define rg register
  7.  
  8. template<class T> inline T dma(rg T x,rg T y) {return x>y?x:y;}
  9. template<class T> inline void read(rg T &x)
  10. {
  11. rg int c=getchar();rg bool b=0;
  12. for(;c<48||c>57;c=getchar())
  13. if(c==45)b=1;
  14. for(x=0;c>47&&c<58;c=getchar())
  15. x=(x<<1)+(x<<3)+c-48;
  16. if(b)x=-x;
  17. }
  18.  
  19. const int N=500010;
  20. std::vector<int>vc;
  21. std::map<int,int>hc;
  22. int n,q,seq[N],fir[N],nex[N],st[20][N],bin[20],lgg[20],ans;
  23.  
  24. void sequence_table()
  25. {
  26. lgg[0]=-1;for(rg int i=1;i<=n;i++)lgg[i]=lgg[i>>1]+1;
  27. for(rg int i=0;i<20;i++)bin[i]=1<<i;
  28. for(rg int i=1;i<=n;i++)st[0][i]=seq[i];
  29. for(rg int t=1;t<20;t++)
  30. for(rg int i=1;i<=n;i++)
  31. if(i+bin[t]-1<=n)st[t][i]=dma(st[t-1][i],st[t-1][i+bin[t-1]]);
  32. }
  33.  
  34. int sequence_query(rg int x,rg int y)
  35. {
  36. rg int t=lgg[y-x+1];
  37. return dma(st[t][x],st[t][y-bin[t]+1]);
  38. }
  39.  
  40. void jump(rg int x,rg int lim)
  41. {
  42. for(rg int rig=x,lef=nex[x];lef>=lim;lef=nex[lef])
  43. {
  44. while(rig>lef&&sequence_query(lef,rig)>seq[lef])rig=nex[rig];
  45. ans=dma(ans,rig-lef+1);
  46. }
  47. }
  48.  
  49. int main()
  50. {
  51. freopen("sequence.in","r",stdin);
  52. freopen("sequence.out","w",stdout);
  53. read(n),read(q);
  54. for(rg int i=1;i<=n;i++)
  55. {
  56. read(seq[i]);
  57. vc.push_back(seq[i]);
  58. }
  59. std::sort(vc.begin(),vc.end());
  60. vc.erase(std::unique(vc.begin(),vc.end()),vc.end());
  61. for(rg int i=0;i<vc.size();i++)
  62. hc[vc[i]]=i+1;
  63. for(rg int i=1;i<=n;i++)seq[i]=hc[seq[i]];
  64. memset(fir,-1,sizeof fir);
  65. for(rg int i=1;i<=n;i++)
  66. {
  67. nex[i]=fir[seq[i]];
  68. fir[seq[i]]=i;
  69. }
  70. sequence_table();
  71. for(rg int x,y;q;q--)
  72. {
  73. ans=1;
  74. read(x),read(y);
  75. for(rg int i=y;i>=x;i--)
  76. jump(i,x);
  77. printf("%d\n",ans);
  78. }
  79. fclose(stdin);
  80. fclose(stdout);
  81. return 0;
  82. }

出题人一定是月厨,有爱~

考虑将这些进行jump的操作序列转化成链,离线后,用链来更新询问

对于所有链长度小于s的,用树状数组区间最值+扫描线做

对于所有链长度大于s的,这样的链只有n/s条,对每条链的下标预处理每个下标i所在链上的位置,对每个询问算出最优值并更新,复杂度为n*n/s

取s=sqrt(n/logn),可以得到O(n*sqrt(n*logn))的复杂度

  1. #include <map>
  2. #include <vector>
  3. #include <math.h>
  4. #include <stdio.h>
  5. #include <string.h>
  6. #include <algorithm>
  7.  
  8. template<class T> T mex(T x,T y) {return x>y?x:y;}
  9. template<class T> void read(T &x)
  10. {
  11. int c=getchar();bool b=0;
  12. for(;c<48||c>57;c=getchar())if(c==45)b=1;
  13. for(x=0;c>47&&c<58;c=getchar())x=(x<<1)+(x<<3)+c-48;
  14. if(b)x=-x;
  15. }
  16.  
  17. const int maxn=500010;
  18. bool vis[maxn];
  19. int n,m,lim,A[maxn],st[20][maxn],lgg[maxn],L[maxn],R[maxn],ans[maxn],nex[maxn],big[maxn],cur[maxn],tr[maxn];
  20.  
  21. std::map<int,int> pool;
  22. std::vector<int> seq;
  23. std::vector<std::pair<int,int> > Q[maxn];
  24.  
  25. inline void Add(int x,int c)
  26. {
  27. for(;x<=n;x+=x&-x)tr[x]=mex(tr[x],c);
  28. }
  29.  
  30. inline int Get(int x)
  31. {
  32. int ret=0;
  33. for(;x;x-=x&-x)ret=mex(ret,tr[x]);
  34. return ret;
  35. }
  36.  
  37. inline int maxi(int x,int y)
  38. {
  39. int t=lgg[++y-x];
  40. return mex(st[t][x],st[t][y-(1<<t)]);
  41. }
  42.  
  43. int main()
  44. {
  45. freopen("sequence.in","r",stdin);
  46. freopen("sequence.out","w",stdout);
  47. read(n),read(m);
  48. lgg[0]=-1;for(int i=1;i<=n;i++)
  49. {
  50. read(A[i]);
  51. st[0][i]=A[i];
  52. lgg[i]=lgg[i>>1]+1;
  53. }
  54. for(int i=1;i<=m;i++)
  55. {
  56. read(L[i]),read(R[i]);
  57. Q[L[i]].push_back(std::make_pair(R[i],i));
  58. ans[i]=1;
  59. }
  60. for(int t=1;t<20;t++)
  61. for(int i=1;i+(1<<t)-1<=n;i++)
  62. st[t][i]=mex(st[t-1][i],st[t-1][i+(1<<t-1)]);
  63. for(int i=n,j;i;i--)
  64. {
  65. if(pool.count(A[i]))
  66. {
  67. j=pool[A[i]];
  68. if(maxi(i,j)<=A[i])nex[i]=j;
  69. }
  70. pool[A[i]]=i;
  71. }
  72. lim=static_cast<int>(sqrt(n/log(n)/log(2)));
  73. for(int i=1;i<=n;i++)
  74. if(!vis[i])
  75. {
  76. seq.clear();
  77. seq.push_back(0);
  78. for(int j=i;j;j=nex[j])
  79. {
  80. seq.push_back(j);
  81. vis[j]=true;
  82. }
  83. if(seq.size()>=lim)
  84. {
  85. for(int j=1,k=0;j<=n;j++)
  86. {
  87. for(;k<seq.size()&&j>=seq[k];k++)big[seq[k]]=1;
  88. cur[j]=k-1;
  89. }
  90. for(int j=1,x,y;j<=m;j++)
  91. if(cur[L[j]-1]+1<seq.size())
  92. {
  93. x=seq[cur[L[j]-1]+1];
  94. y=seq[cur[R[j]]];
  95. ans[j]=mex(ans[j],y-x+1);
  96. }
  97. }
  98. }
  99. for(int i=n;i;i--)
  100. {
  101. if(!big[i])
  102. for(int j=i;j;j=nex[j])
  103. Add(j,j-i+1);
  104. for(int j=0;j<Q[i].size();j++)
  105. ans[Q[i][j].second]=mex(ans[Q[i][j].second],Get(Q[i][j].first));
  106. }
  107. for(int i=1;i<=m;i++)printf("%d\n",ans[i]);
  108. fclose(stdin);
  109. fclose(stdout);
  110. return 0;
  111. }

  

NOI模拟(3.3)螺旋序列(出题人一定是月厨)的更多相关文章

  1. Java实现 LeetCode 521 最长特殊序列 Ⅰ(出题人:“就是喜欢看你们不敢相信那么简单,又不敢提交的样子。”)

    521. 最长特殊序列 Ⅰ 给定两个字符串,你需要从这两个字符串中找出最长的特殊序列.最长特殊序列定义如下:该序列为某字符串独有的最长子序列(即不能是其他字符串的子序列). 子序列可以通过删去字符串中 ...

  2. NOI 模拟赛 #2

    得分非常惨惨,半个小时写的纯暴力 70 分竟然拿了 rank 1... 如果 OYJason 和 wxjor 在可能会被爆踩吧 嘤 T1 欧拉子图 给一个无向图,如果一个边集的导出子图是一个欧拉回路, ...

  3. D.出题人的手环

    链接:https://ac.nowcoder.com/acm/contest/358/D 题意: 出题人的妹子送了出题人一个手环,这个手环上有 n 个珠子,每个珠子上有一个数. 有一天,出题人和妹子分 ...

  4. ACM_出题人这样不好吧

    出题人这样不好吧 Time Limit: 2000/1000ms (Java/Others) Problem Description: 作为编协的第一次月赛,肯定是要有防AK(ALL KILL)的题目 ...

  5. 牛客 545C 出题人的数组 (贪心)

    出题人有两个数组A,B,请你把两个数组归并起来使得$cost=\sum i c_i$最小. 归并要求原数组的数的顺序在新数组中不改变. 贪心水题 对于一段序列$A_i,A_{i+1},...,A_r$ ...

  6. 6.6 NOI 模拟

    \(T1\)括号序列 --那是,朝思夜想也未尝得到的自由 一个比较常见的转化,考虑如何判断前一段和后一段能够拼成一个合法的括号序列 充要条件: 前半部分,'('看为\(1\), ')'看为\(-1\) ...

  7. 5.6 NOI模拟

    \(5.6\ NOI\)模拟 明天就母亲节了,给家里打了个电话(\(lj\ hsez\)断我电话的电,在宿舍打不了,只能用教练手机打了) 其实我不是很能看到自己的\(future,\)甚至看不到高三的 ...

  8. 5.4 NOI模拟

    \(5.4\ NOI\)模拟 \(T1\) 想到分讨,但是暴力输出一下方案之后有很多特别的情况要讨论,就弃了... 假设\(a\)是原序列,\(b\)是我们得到的序列 设\(i\)是最长公共前缀,\( ...

  9. 牛客练习赛38 D 出题人的手环

    链接 [https://ac.nowcoder.com/acm/contest/358/D] 题意 链接:https://ac.nowcoder.com/acm/contest/358/D 来源:牛客 ...

随机推荐

  1. Logstash读取文本信息并写入到ES

    Logstash读取文本信息并写入到ES 前提是ELK安装没问题 进入到logstash安装目录下的bin目录(我的logstash安装目录:/usr/local/) [root@es1 bin]# ...

  2. java 调用动态库打包sdk

    java连接c++动态库并生成jar包提供给别人调用 1.需要将java通过jni生成头文件,并导入到c++项目并对c++进行jni方法继承 在项目的src目录执行,否则会提示 错误:找不到符号 ja ...

  3. Kubernetes集群认证

    1.集群搭建:https://www.kubernetes.org.cn/3808.html 2.集群验证:https://www.kubernetes.org.cn/1861.html

  4. bzoj258 [USACO 2012 Jan Gold] Bovine Alliance【巧妙】

    传送门1:http://www.usaco.org/index.php?page=viewproblem2&cpid=111 传送门2:http://www.lydsy.com/JudgeOn ...

  5. egrep命令的实现 分类: 编译原理 2014-06-01 23:41 329人阅读 评论(0) 收藏

    本程序实现了egrep命令,首先将正则表达式转换为NFA,并实现模拟NFA的算法. 本程序使用flex实现词法分析,bison实现语法分析 若给定的一行字符串中存在一个字串能被该NFA接受,则输出整行 ...

  6. jsp声明周期

    https://www.w3cschool.cn/jsp/jsp-life-cycle.html 几点注意: jsp初始化期: 容器载入jsp文件后,它会在为请求提供任何服务前调用jspinit()方 ...

  7. 转】用Nodejs连接MySQL

    原博文出自于: http://blog.fens.me/category/%E6%95%B0%E6%8D%AE%E5%BA%93/page/2/ 感谢! 用Nodejs连接MySQL 从零开始node ...

  8. [书目20141009]《ReWork》

    ReWork1: ============= 引言篇INTRODUCTION开局篇FIRST 新的现实缷负篇TAKEDOWNS 忘了“现实世界” 哪来的从错误中学习 计划即瞎猜 何必壮大? 工作狂 受 ...

  9. Hibernate配置(外部配置文件方式)

    配置Hibernate有2种方式,本文讲的是通过外部配置文件配置的方式 Hibernate核心配置文件 <?xml version='1.0' encoding='UTF-8'?> < ...

  10. [BZOJ1046][HAOI2007]上升序列 DP+贪心

    题目链接:http://www.lydsy.com/JudgeOnline/problem.php?id=1046 我们先求出对于每一个数字作为开头的LCS的长度f[i],最长的f[i]为mxlen. ...