HDU6602 Longest Subarray 线段树

传送门:http://acm.hdu.edu.cn/showproblem.php?pid=6602

题意:

给你一段区间,让你求最长的区间使得区间出现的数字的个数大于k

题解:

比较巧妙的的线段树更新的做法

我们选择的区间吗,该区间内出现的数字的个数必须要满足条件

我们转换一下,我们以当前点为右端点,往左找一个满足条件的左端点,即可更新答案

我们将每个点给予一个权值C-1,更新这个点的数字上次出现的位置之前到现在这个位置-1的一段减1

如果满足这个点的值出现的次数大于k次的话,我们将上一次满足出现k次出现的一段位置给加上1

最后得到当前位置之前满足条件的左端点更新答案

这里巧妙的使用了条件作为线段树查询的条件,所以线段树查询出来的左端点就是满足条件的最远的左端点

代码:

  1. #include <set>
  2. #include <map>
  3. #include <stack>
  4. #include <cmath>
  5. #include <queue>
  6. #include <cstdio>
  7. #include <string>
  8. #include <vector>
  9. #include <cstring>
  10. #include <iostream>
  11. #include <algorithm>
  12. using namespace std;
  13. typedef long long LL;
  14. typedef pair<int, int> pii;
  15. typedef unsigned long long uLL;
  16. #define ls rt<<1
  17. #define rs rt<<1|1
  18. #define lson l,mid,rt<<1
  19. #define rson mid+1,r,rt<<1|1
  20. #define bug printf("*********\n")
  21. #define FIN freopen("input.txt","r",stdin);
  22. #define FON freopen("output.txt","w+",stdout);
  23. #define IO ios::sync_with_stdio(false),cin.tie(0)
  24. #define debug1(x) cout<<"["<<#x<<" "<<(x)<<"]\n"
  25. #define debug2(x,y) cout<<"["<<#x<<" "<<(x)<<" "<<#y<<" "<<(y)<<"]\n"
  26. #define debug3(x,y,z) cout<<"["<<#x<<" "<<(x)<<" "<<#y<<" "<<(y)<<" "<<#z<<" "<<z<<"]\n"
  27. const int maxn = 3e5 + 5;
  28. const int INF = 0x3f3f3f3f;
  29. const int mod = 1e9 + 7;
  30. const double Pi = acos(-1);
  31. /*
  32. 如果右端点固定,对于每种元素,可行的左端点下标是两段连续的区间。
  33. 对于每种元素,将它的可行左端点区间在线段树中加1。
  34. 当右端点右移的时候,维护C 种元素的可行左端点。
  35. 查询时只要询问线段树中札小的、值为C 的下标即可。*/
  36. LL quick_pow(LL x, LL y) {
  37. LL ans = 1;
  38. while(y) {
  39. if(y & 1) {
  40. ans = ans * x % mod;
  41. } x = x * x % mod;
  42. y >>= 1;
  43. } return ans;
  44. }
  45. int n, C, k;
  46. int Max[maxn << 2];
  47. int lazy[maxn << 2];
  48. int pos[maxn << 2];
  49. void push_up(int rt) {
  50. Max[rt] = max(Max[ls], Max[rs]);
  51. pos[rt] = (Max[rt] == Max[ls] ? pos[ls] : pos[rs]);
  52. }
  53. void build(int l, int r, int rt) {
  54. Max[rt] = lazy[rt] = 0;
  55. pos[rt] = l;
  56. if(l == r) return;
  57. int mid = (l + r) >> 1;
  58. build(lson);
  59. build(rson);
  60. }
  61. void push_down(int rt) {
  62. if(lazy[rt]) {
  63. lazy[ls] += lazy[rt];
  64. lazy[rs] += lazy[rt];
  65. Max[ls] += lazy[rt];
  66. Max[rs] += lazy[rt];
  67. lazy[rt] = 0;
  68. }
  69. }
  70. void update(int L, int R, int val, int l, int r, int rt) {
  71. if(L > R) return;
  72. if(L <= l && r <= R) {
  73. Max[rt] += val;
  74. lazy[rt] += val;
  75. return;
  76. }
  77. push_down(rt);
  78. int mid = (l + r) >> 1;
  79. if(L <= mid) update(L, R, val, lson);
  80. if(R > mid) update(L, R, val, rson);
  81. push_up(rt);
  82. }
  83. int query(int L, int R, int l, int r, int rt) {
  84. if(Max[rt] != C) return 0;
  85. if(L <= l && r <= R) {
  86. return pos[rt];
  87. }
  88. int mid = (l + r) >> 1;
  89. push_down(rt);
  90. if(L <= mid) {
  91. int t = query(L, R, lson);
  92. if(t) return t;
  93. }
  94. if(R > mid) return query(L, R, rson);
  95. return 0;
  96. }
  97. vector<int> vec[maxn];
  98. int main() {
  99. #ifndef ONLINE_JUDGE
  100. FIN
  101. #endif
  102. while(scanf("%d%d%d", &n, &C, &k) != EOF) {
  103. for(int i = 1; i <= C; i++) {
  104. vec[i].clear();
  105. vec[i].push_back(0);
  106. }
  107. build(1, n, 1);
  108. int ans = 0;
  109. for(int i = 1; i <= n; i++) {
  110. int c;
  111. scanf("%d", &c);
  112. update(i, i, C - 1, 1, n, 1);
  113. update(vec[c].back() + 1, i - 1, -1, 1, n, 1);
  114. vec[c].push_back(i);
  115. int p = vec[c].size() - k - 1;
  116. if(p >= 0) {
  117. update(vec[c][p] + 1, vec[c][p + 1], 1, 1, n, 1);
  118. }
  119. int j = query(1, i, 1, n, 1);
  120. if(!j) continue;
  121. ans = max(ans, i - j + 1);
  122. }
  123. printf("%d\n", ans);
  124. }
  125. return 0;
  126. }

HDU6602 Longest Subarray hdu多校第二场 线段树的更多相关文章

  1. HDU 4614 Vases and Flowers (2013多校第二场线段树)

    题意摘自:http://blog.csdn.net/kdqzzxxcc/article/details/9474169 ORZZ 题意:给你N个花瓶,编号是0 到 N - 1 ,初始状态花瓶是空的,每 ...

  2. hdu多校第二场1008(hdu6598) Harmonious Army 最小割

    题意: 一个军队有n人,你可以给他们每个人安排战士或者法师的职业,有m对人有组合技,组合技的信息是a,b,c,代表如果这两个人是两个战士,则组合技威力为a,一个战士一个法师,威力为b,其中b=a/4+ ...

  3. hdu多校第二场 1005 (hdu6595) Everything Is Generated In Equal Probability

    题意: 给定一个N,随机从[1,N]里产生一个n,然后随机产生一个n个数的全排列,求出n的逆序数对的数量,加到cnt里,然后随机地取出这个全排列中的一个非连续子序列(注意这个子序列可以是原序列),再求 ...

  4. hdu多校第二场1009 (hdu6599) I Love Palindrome String 回文自动机/字符串hash

    题意: 找出这样的回文子串的个数:它本身是一个回文串,它的前一半也是一个回文串 输出格式要求输出l个数字,分别代表长度为1~l的这样的回文串的个数 题解: (回文自动机和回文树是一个东西) 首先用回文 ...

  5. hdu多校第二场1011 (hdu6601) Keen On Everything But Triangle 主席树

    题意: 给定一个数列,每次询问一个区间,问这个区间中的值可组成的周长最大的三角形的周长. 题解: 定理1:给定一些值,这些值中组成边长最大的三角形的三条边的大小排名一定是连续的. 证明:假如第k大,第 ...

  6. hdu多校第二场 1010 (hdu6600)Just Skip This Problem

    题意: 给你一个数x,允许你多次询问yi,然后回答你x xor yi 是否等于yi,询问尽量少的次数以保证能求出xi是几,求出这样询问次数最少的询问方案数. 结果mod1e6+3 题解: 队友赛时很快 ...

  7. 2019牛客多校第二场 A Eddy Walker(概率推公式)

    2019牛客多校第二场 A Eddy Walker(概率推公式) 传送门:https://ac.nowcoder.com/acm/contest/882/A 题意: 给你一个长度为n的环,标号从0~n ...

  8. hdu 5861 Road 两棵线段树

    传送门:hdu 5861 Road 题意: 水平线上n个村子间有 n-1 条路. 每条路开放一天的价格为 Wi 有 m 天的操作,每天需要用到村子 Ai~Bi 间的道路 每条路只能开放或关闭一次. ( ...

  9. HDU 3016 Man Down (线段树+dp)

    HDU 3016 Man Down (线段树+dp) Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Ja ...

随机推荐

  1. oracle回滚机制深入研究

    这篇文章主要描写叙述oracle的回滚机制,篇幅可能较长,由于对于oracle的回滚机制来说,要讨论和描写叙述的实在太多,仅仅能刷选自己觉得最有意义的一部分进行深入研究和分享 一.我们来看一个DML语 ...

  2. iOS小技巧:用runtime 解决UIButton 重复点击问题

    http://www.cocoachina.com/ios/20150911/13260.html 作者:uxyheaven 授权本站转载. 什么是这个问题 我们的按钮是点击一次响应一次, 即使频繁的 ...

  3. MaxCompute客户端(odpscmd)在windows命令行下查询中文乱码问题处理实践

    MaxCompute客户端工具是阿里云大数据计算服务MaxCompue产品官方客户端工具,通过客户端工具可以连接MaxCompute项目,完成包括数据管理.数据上下传.作业执行.用户及授权管理等各项操 ...

  4. 2018-7-9-dotnet-设计规范-·-数组定义

    title author date CreateTime categories dotnet 设计规范 · 数组定义 lindexi 2018-07-09 14:26:48 +0800 2018-2- ...

  5. @loj - 2461@ 「2018 集训队互测 Day 1」完美的队列

    目录 @description@ @solution@ @part - 0@ @part - 1@ @accepted code@ @details@ @description@ 小 D 有 n 个 ...

  6. 洛谷P2455 [SDOI2006]线性方程组

    高斯消元模板 要求输出解的情况(无穷解/无解) 1. 之前写的丑陋代码 #include <iostream> #include <cstdio> #include <c ...

  7. oracle函数 CONCAT(c1,c2)

    [功能]连接两个字符串 [参数]c1,c2 字符型表达式 [返回]字符型 同:c1||c2 [示例] select concat('010-','88888888')||'转23' 高乾竞电话 fro ...

  8. Redis源码解析:01简单动态字符串SDS

    Redis没有直接使用C字符串(以'\0'结尾的字符数组),而是构建了一种名为简单动态字符串( simple  dynamic  string, SDS)的抽象类型,并将SDS用作Redis的默认字符 ...

  9. php开发微信支付获取用户地址

    http://mp.weixin.qq.com/s/uNpWE_Z5RZ48PDIWkmGBYQ 使用微信获取地址信息是和微信支付一道申请的,微信支付申请通过,就可以使用该功能. 微信商城中,使用微信 ...

  10. jQuery仿迅雷图片轮换效果

    jQuery仿迅雷图片轮换效果 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "ht ...