#2051. 「HNOI2016」序列

题目描述

给定长度为 n nn 的序列:a1,a2,⋯,an a_1, a_2, \cdots , a_na​1​​,a​2​​,⋯,a​n​​,记为 a[1:n] a[1 \colon n]a[1:n]。类似地,a[l:r] a[l \colon r]a[l:r](1≤l≤r≤N 1 \leq l \leq r \leq N1≤l≤r≤N)是指序列:al,al+1,⋯,ar−1,ar a_{l}, a_{l+1}, \cdots ,a_{r-1}, a_ra​l​​,a​l+1​​,⋯,a​r−1​​,a​r​​。若 1≤l≤s≤t≤r≤n1\leq l \leq s \leq t \leq r \leq n1≤l≤s≤t≤r≤n,则称 a[s:t] a[s \colon t]a[s:t]是 a[l:r] a[l \colon r]a[l:r] 的子序列。

现在有 q qq 个询问,每个询问给定两个数 l ll 和 r rr,1≤l≤r≤n 1 \leq l \leq r \leq n1≤l≤r≤n,求 a[l:r] a[l \colon r]a[l:r] 的不同子序列的最小值之和。例如,给定序列 5,2,4,1,3 5, 2, 4, 1, 35,2,4,1,3,询问给定的两个数为 1 11 和 3 33,那么 a[1:3] a[1 \colon 3]a[1:3] 有 6 66 个子序列 a[1:1],a[2:2],a[3:3],a[1:2],a[2:3],a[1:3]a[1 \colon 1], a[2 \colon 2], a[3 \colon 3], a[1 \colon 2],a[2 \colon 3], a[1 \colon 3]a[1:1],a[2:2],a[3:3],a[1:2],a[2:3],a[1:3],这 666 个子序列的最小值之和为 5+2+4+2+2+2=175+2+4+2+2+2=175+2+4+2+2+2=17。

输入格式

输入文件的第一行包含两个整数 n nn 和 q qq,分别代表序列长度和询问数。
接下来一行,包含 n nn 个整数,以空格隔开,第 i ii 个整数为 ai a_ia​i​​,即序列第 iii 个元素的值。
接下来 q qq 行,每行包含两个整数 l ll 和 r rr,代表一次询问。

输出格式

对于每次询问,输出一行,代表询问的答案。

样例

样例输入

  1. 5 5
  2. 5 2 4 1 3
  3. 1 5
  4. 1 3
  5. 2 4
  6. 3 5
  7. 2 5

样例输出

  1. 28
  2. 17
  3. 11
  4. 11
  5. 17

数据范围与提示

对于 100%100\%100% 的数据,1≤n,q≤100000,∣ai∣≤109 1 \leq n,q \leq 100000 ,|a_i| \leq 10^91≤n,q≤100000,∣a​i​​∣≤10​9​​

  1. #include<iostream>
  2. #include<cstdio>
  3. #include<cstring>
  4. #define maxn 100010
  5. using namespace std;
  6. int n,q,a[maxn],L[maxn],R[maxn],to[maxn];
  7. void make(int i){
  8. L[i]=R[i]=i;
  9. int l=i,r=i;
  10. while(a[l-]>=a[i]&&l>)l--;
  11. while(a[r+]>=a[i]&&r<n)r++;
  12. L[i]=l;R[i]=r;
  13. }
  14. int main(){
  15. scanf("%d%d",&n,&q);
  16. for(int i=;i<=n;i++)scanf("%d",&a[i]);
  17. for(int i=;i<=n;i++)make(i);
  18. for(int i=;i<=n;i++)
  19. for(int j=i+;j<=n;j++)
  20. if(a[i]==a[j]){to[i]=j;break;}
  21. int x,y;
  22. while(q--){
  23. long long ans=;
  24. scanf("%d%d",&x,&y);
  25. for(int i=x;i<=y;i++){
  26. if(to[i]&&i>=L[to[i]])continue;
  27. int l=max(x,L[i]),r=min(y,R[i]);
  28. ans+=1LL*(i-l+)*(r-i+)*a[i];
  29. }
  30. cout<<ans<<endl;
  31. }
  32. }

40分 暴力

  1. #include<iostream>
  2. #include<cstdio>
  3. #include<cstring>
  4. #include<algorithm>
  5. #include<cmath>
  6. #define maxn 200010
  7. using namespace std;
  8. long long lg[maxn],mn[maxn][],a[maxn],mnid[maxn][];
  9. long long belong[maxn],Ans[maxn],fl[maxn],fr[maxn],sta[maxn],top;
  10. struct node{
  11. int l,r,id;
  12. bool operator < (const node &b)const{
  13. if(belong[l]==belong[b.l])return r<b.r;
  14. return belong[l]<belong[b.l];
  15. }
  16. }q[maxn];
  17. long long qread(){
  18. long long i=,j=;
  19. char ch=getchar();
  20. while(ch<''||ch>''){if(ch=='-')j=-;ch=getchar();}
  21. while(ch<=''&&ch>=''){i=i*+ch-'';ch=getchar();}
  22. return i*j;
  23. }
  24. void pre(long long n){//st表
  25. lg[]=;
  26. for(int i=;i<=n;i++){
  27. lg[i]=lg[i-];
  28. if(i==(<<lg[i]+))lg[i]++;
  29. }
  30. for(int i=n;i>=;i--){
  31. mn[i][]=a[i];
  32. mnid[i][]=i;
  33. for(int j=;i+(<<j)-<=n;j++){
  34. mn[i][j]=min(mn[i][j-],mn[i+(<<j-)][j-]);
  35. if(mn[i][j]==mn[i][j-])mnid[i][j]=mnid[i][j-];
  36. if(mn[i][j]==mn[i+(<<j-)][j-])mnid[i][j]=mnid[i+(<<j-)][j-];
  37. }
  38. }
  39. }
  40. long long query(long long l,long long r){
  41. long long k=lg[r-l+];
  42. if(mn[l][k]<mn[r-(<<k)+][k])return mnid[l][k];
  43. return mnid[r-(<<k)+][k];
  44. }
  45. void dp(long long n,long long *f){//单调栈
  46. sta[top=]=;
  47. for(int i=;i<=n;i++){
  48. while(a[sta[top]]>a[i])top--;
  49. f[i]=(i-sta[top])*a[i]+f[sta[top]];
  50. sta[++top]=i;
  51. }
  52. }
  53. long long up_r(long long l,long long r){
  54. long long p=query(l,r+);
  55. return (p-l+)*a[p]+fl[r+]-fl[p];
  56. }
  57. long long up_l(long long l,long long r){
  58. long long p=query(l-,r);
  59. return (r-p+)*a[p]+fr[l-]-fr[p];
  60. }
  61. int main(){
  62. freopen("Cola.txt","r",stdin);
  63. int n,Q;
  64. n=qread();Q=qread();
  65. a[]=-(1LL<<);
  66. for(int i=;i<=n;i++)a[i]=qread();
  67. pre(n);dp(n,fl);
  68. reverse(a+,a+n+);
  69. dp(n,fr);
  70. reverse(a+,a+n+);reverse(fr+,fr+n+);
  71. int block=sqrt(n)+;
  72. for(int i=;i<=n;i++)belong[i]=(i/block)+;
  73. for(int i=;i<=Q;i++){
  74. q[i].l=qread();q[i].r=qread();
  75. q[i].id=i;
  76. }
  77. sort(q+,q+Q+);
  78. a[]=;
  79. int l=,r=;long long ans=a[];
  80. for(int i=;i<=Q;i++){
  81. while(r<q[i].r)ans+=up_r(l,r++);
  82. while(r>q[i].r)ans-=up_r(l,--r);
  83. while(l>q[i].l)ans+=up_l(l--,r);
  84. while(l<q[i].l)ans-=up_l(++l,r);
  85. Ans[q[i].id]=ans;
  86. }
  87. for(int i=;i<=Q;i++)cout<<Ans[i]<<endl;
  88. return ;
  89. }

100分 莫队+st表+单调栈

loj #2051. 「HNOI2016」序列的更多相关文章

  1. Loj #3059. 「HNOI2019」序列

    Loj #3059. 「HNOI2019」序列 给定一个长度为 \(n\) 的序列 \(A_1, \ldots , A_n\),以及 \(m\) 个操作,每个操作将一个 \(A_i\) 修改为 \(k ...

  2. 「HNOI2016」序列 解题报告

    「HNOI2016」序列 有一些高妙的做法,懒得看 考虑莫队,考虑莫队咋移动区间 然后你在区间内部找一个最小值的位置,假设现在从右边加 最小值左边区间显然可以\(O(1)\),最小值右边的区间是断掉的 ...

  3. LOJ 3158: 「NOI2019」序列

    题目传送门:LOJ #3158. 题意简述: 给定两个长度为 \(n\) 的正整数序列 \(a,b\),要求在每个序列中都选中 \(K\) 个下标,并且要保证同时在两个序列中都被选中的下标至少有 \( ...

  4. LOJ #2183「SDOI2015」序列统计

    有好多好玩的知识点 LOJ 题意:在集合中选$ n$个元素(可重复选)使得乘积模$ m$为$ x$,求方案数对$ 1004535809$取模 $ n<=10^9,m<=8000且是质数,集 ...

  5. LOJ 3059 「HNOI2019」序列——贪心与前后缀的思路+线段树上二分

    题目:https://loj.ac/problem/3059 一段 A 选一个 B 的话, B 是这段 A 的平均值.因为 \( \sum (A_i-B)^2 = \sum A_i^2 - 2*B \ ...

  6. loj#2049. 「HNOI2016」网络(set 树剖 暴力)

    题意 题目链接 Sol 下面的代码是\(O(nlog^3n)\)的暴力. 因为从一个点向上只会跳\(logn\)次,所以可以暴力的把未经过的处理出来然后每个点开个multiset维护最大值 #incl ...

  7. LOJ #2048. 「HNOI2016」最小公倍数

    题意 有 \(n\) 个点,\(m\) 条边,每条边连接 \(u \Leftrightarrow v\) 且权值为 \((a, b)\) . 共有 \(q\) 次询问,每次询问给出 \(u, v, q ...

  8. loj#2002. 「SDOI2017」序列计数(dp 矩阵乘法)

    题意 题目链接 Sol 质数的限制并没有什么卵用,直接容斥一下:答案 = 忽略质数总的方案 - 没有质数的方案 那么直接dp,设\(f[i][j]\)表示到第i个位置,当前和为j的方案数 \(f[i ...

  9. LOJ#2052. 「HNOI2016」矿区(平面图转对偶图)

    题面 传送门 题解 总算会平面图转对偶图了-- 首先我们把无向边拆成两条单向边,这样的话每条边都属于一个面.然后把以每一个点为起点的边按极角排序,那么对于一条边\((u,v)\),我们在所有以\(v\ ...

随机推荐

  1. java成神之——数值操作BigDecimal,BigInteger,Random,SecureRandom

    数值操作 数值新特性 包装类 浮点 BigDecimal BigInteger 数值本地化 随机数 假随机数 真随机数 播种 结语 数值操作 数值新特性 123_456 等价于 123456,增加可读 ...

  2. 使用Java进行远程方法调用的几个方案及比较

    Java远程方法调用是编程过程中比较常见的问题,列举一下主要包括如下几类: 1.Java RMI (Remote Method Invocation) 2.EJB远程接口调用 3.WebService ...

  3. wireshark怎么抓包、wireshark抓包详细图文教程(转)

    wireshark怎么抓包.wireshark抓包详细图文教程 wireshark是非常流行的网络封包分析软件,功能十分强大.可以截取各种网络封包,显示网络封包的详细信息.使用wireshark的人必 ...

  4. Spring Cloud Eureka 5 (服务发现与消费-简单的robbin使用)

    通过上述介绍,我们已经有了服务注册中心和服务提供者 下面我们来尝试构建一个服务的消费者 它要完成两个功能,发现服务和消费服务,其中发现服务由eureka客户端完成,消费服务由ribbon完成. rib ...

  5. redis-win7

    http://blog.csdn.net/renfufei/article/details/38474435

  6. 安装saltstack-web管理界面

    1.安装salt-master.salt-minion和salt-api $ sudo yum install epel-release -y $ sudo yum install salt-mast ...

  7. 【bzoj1083】[SCOI2005]繁忙的都市

    1083: [SCOI2005]繁忙的都市 Time Limit: 10 Sec  Memory Limit: 162 MBSubmit: 2424  Solved: 1591[Submit][Sta ...

  8. 分布式文件系统MFS(moosefs)实现存储共享

    分布式文件系统MFS(moosefs)实现存储共享(第二版) 作者:田逸(sery@163.com) 由于用户数量的不断攀升,我对访问量大的应用实现了可扩展.高可靠的集群部署(即lvs+keepali ...

  9. 关于getchar的一些思考

    这个问题是有一段代码引起的: 代码1: #include<iostream> using namespace std; int main() { char t; t=getchar(); ...

  10. dynamic和匿名类和var的混合使用 没提示照样点

    using System;using System.Collections;using System.Collections.Generic;using System.Linq;using Syste ...