题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=6701

题目大意为求满足 $max(a_{l},a_{l+1}\cdot \cdot \cdot a_{r})-(r-l+1)<=k$的区间个数。

先预处理出前缀最大值和后缀最大值和ST表,然后分治。

每次可以得到这次分治区间的区间最大值,然后我们要求出以该最大值为区间最大值时的合法区间数目。

这里我们可以枚举合法区间的左端点(右端点),然后通过化简上式得到合法的右端点(左端点),选择枚举左还是右端点由当前区间最大值的位置所决定,因为左端点一定在最大值左边,右端点一定在最大值右边,所以选择数量较小的一边来枚举。

 1 #include<cstdio>
 2 #include<cstring>
 3 #include<algorithm>
 4 #include<iostream>
 5 #include<set>
 6 using namespace std;
 7 typedef long long ll;
 8 typedef unsigned long long ull;
 9 const int maxn = 3e5 + 110;
10 int a[maxn], pos[maxn], L[maxn], R[maxn], Log[maxn];
11 int n, k;
12 int dp[maxn][20];
13 int query(int l, int r) {
14     int k = Log[r - l + 1];
15     if (a[dp[l][k]] > a[dp[r - (1 << k) + 1][k]])
16         return dp[l][k];
17     else
18         return dp[r - (1 << k) + 1][k];
19 }
20 ll dfs(int l, int r) {
21     if (l == r)return a[l] - 1 <= k;
22     if (l > r)return 0;
23     int cnt = query(l, r);
24     ll ans = 0;
25     if (cnt - l < r - cnt) {
26         for (int i = l; i <= cnt; i++) {
27             int ls = max(cnt, i + a[cnt] - k - 1);
28             int rs = min(r, R[i]);
29             if (rs >= ls)
30                 ans += rs - ls + 1;
31         }
32     }
33     else {
34         for (int i = cnt; i <= r; i++) {
35             int ls = max(l, L[i]);
36             int rs = min(i - (a[cnt] - k) + 1, cnt);
37             if (rs >= ls) ans += rs - ls + 1;
38         }
39     }
40     return ans + dfs(l, cnt - 1) + dfs(cnt + 1, r);
41 }
42 int main() {
43     int t;
44     scanf("%d", &t);
45     while (t--) {
46         scanf("%d%d", &n, &k);
47         for (int i = 1; i <= n; i++)
48             scanf("%d", &a[i]);
49         Log[0] = -1;
50         for (int i = 1; i <= n; i++) Log[i] = Log[i >> 1] + 1;
51         for (int i = 1; i <= n; i++)
52             dp[i][0] = i;
53         for (int j = 1; (1 << j) <= n; j++) {
54             for (int i = 1; i + (1 << j) - 1 <= n; i++) {
55                 if (a[dp[i][j - 1]] > a[dp[i + (1 << (j - 1))][j - 1]])
56                     dp[i][j] = dp[i][j - 1];
57                 else
58                     dp[i][j] = dp[i + (1 << (j - 1))][j - 1];
59             }
60         }
61         for (int i = 0; i <= n; i++)pos[i] = 0;
62         R[n + 1] = n;
63         for (int i = n; i >= 1; i--) {
64             if (pos[a[i]]) {
65                 R[i] = pos[a[i]] - 1;
66                 pos[a[i]] = i;
67             }
68             else {
69                 pos[a[i]] = i;
70                 R[i] = n;
71             }
72             R[i] = min(R[i], R[i + 1]);
73         }
74         for (int i = 0; i <= n; i++)pos[i] = 0;
75         for (int i = 1; i <= n; i++) {
76             if (pos[a[i]]) {
77                 L[i] = pos[a[i]] + 1;
78                 pos[a[i]] = i;
79             }
80             else {
81                 pos[a[i]] = i;
82                 L[i] = 1;
83             }
84             L[i] = max(L[i], L[i - 1]);
85         }
86         printf("%lld\n", dfs(1, n));
87     }
88 }

转载于:https://www.cnblogs.com/sainsist/p/11414393.html

[2019杭电多校第十场][hdu6701]Make Rounddog Happy相关推荐

  1. 【2019.08.21】2019杭电多校第十场

    补题地址:http://acm.hdu.edu.cn/listproblem.php?vol=58 题号:6691-6701 1001: 1002: 1003:✅ 1004: 1005:✅ 1006: ...

  2. 2019杭电多校 第七场 Kejin Player 6656(求期望值)

    2019杭电多校 第七场 Kejin Player 6656(求期望值) 题目 http://acm.hdu.edu.cn/showproblem.php?pid=6656 题意 给你n,q.表示有n ...

  3. 2019杭电多校第9场1002 Rikka with Cake HDU6681

    2019杭电多校第9场1002 Rikka with Cake HDU6681 题意:给你若干个点按上下左右切割平面,最后问平面内有几块被切割开来. 解法1:红黑树+思维+贪心 A:根据欧拉定理可以得 ...

  4. 杭电多校第十场 hdu6434 Count 欧拉函数打表 快速打表模板

    Problem I. Count Time Limit: 4000/2000 MS (Java/Others)    Memory Limit: 524288/524288 K (Java/Other ...

  5. 2019 杭电多校第六场 题解

    比赛记录 注意随机数据 ,1-n排列这种,一般都有啥暴力重构之类的方法,期望重构次数很少之类的 1005也是这样,因为n^2但只有n个值有数,所以就可以n^2logn 题解 1001 Salty Fi ...

  6. 2019杭电多校第三场 6608 Fansblog(威尔逊定理+miller_rabin素性测试)

    Problem Description 传送门 Farmer John keeps a website called 'FansBlog' .Everyday , there are many peo ...

  7. 2019 杭电 多校第3场 1006 Fansblog (HDU 6608)

    题目链接 题解: 用威尔逊定理变换,然后求逆元. 代码: #include <bits/stdc++.h> using namespace std; typedef long long l ...

  8. hdu 6656 2019杭电多校第7场 期望题

    设f[i]为从i升级到i+1期望需要的金钱,由于每级都是能倒退或者升级到i+1,所以询问从l,r的期望金钱可以直接前缀和,那么推导每一级升级需要的期望钱也可以用前缀和推导 设sum[i]=f[1]+f ...

  9. 2019杭电多校第7场 K Kejin Player HDU 6656(数学推导)

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=6656 题目大意:对于每一个等级,可以花ai元,有pi概率升级,如果升级失败就退到xi级,问从li级升到 ...

  10. 2019杭电多校第七场 HDU - 6656 Kejin Player 期望

    题目链接:https://vjudge.net/problem/HDU-6656 题解: 维护一个前缀sum[i] : 从1到 i 的期望 第 i 到达 i + 1是:ai + (1 - r[i] / ...

最新文章

  1. 如何在 CentOS 上启用 软件集 Software Collections(SCL)
  2. oracle查对象创建时间,oracle:查询某个时间之后,指定用户,指定对象类型,并创建的表的个数...
  3. linux mysql 分区_Linux :linux磁盘分区(普通分区2T以内),安装免安装版mysql(tar.gz)...
  4. Silverlight 同域WCF免跨域文件
  5. WiredTiger存储引擎知多少?
  6. Only Link: Inheritance — private and protected inheritance in c++
  7. 在Extjs中对日期的处理,以及在后端数据在SQL语句的判断处理
  8. 【李宏毅2020 ML/DL】P13 Backpropagation | 神经网络反向传播到底是怎么计算的
  9. 【java学习之路】(java SE篇)003.java SE基础语法之数组
  10. Python 的OOP 面向对象编程基础
  11. node on mac
  12. Lumerical官方案例、FDTD时域有限差分法仿真学习(六)——等离子体超材料吸收器(Plasmonic metamaterial absorber)
  13. 机器学习(Machine Learning)深度学习(Deep Learning)资料(Chapter 2)
  14. oracle19c创建表空间,Oracle19c 创建表空间
  15. C/C++语言100题练习计划 97——素数对
  16. 【JS】Javascript中的this到底是什么
  17. ccna网络工程师考试_PrepAway提供的Cisco CCNA无线认证考试问题-建立成功的网络工程师的职业
  18. Kubernetes(K8s)集群安装部署
  19. 【java环境搭建详细教程】
  20. fliecmp库:Python比较文件操作

热门文章

  1. GDI+中发生一般性错误 Winform Image.Save(mstream, ImageFormat.Png)引发
  2. Python学习1——语法
  3. Python基础学习----异常
  4. delphi win64 DEBUG不能进预设断点的问题
  5. ORACLE创建表空间、用户语句
  6. 2013年全国各大著名的IT公司薪资待遇大揭密 给出入职场的民工一点建议
  7. php 调试环境配置
  8. 重磅!Google ARCore 和京东 AR 联合举办消费应用创新大赛
  9. 关于分块思想的个人理解
  10. 聊聊kafka consumer offset lag的监控