[BZOJ4636]蒟蒻的数列

试题描述

蒟蒻DCrusher不仅喜欢玩扑克,还喜欢研究数列
题目描述
DCrusher有一个数列,初始值均为0,他进行N次操作,每次将数列[a,b)这个区间中所有比k小的数改为k,他想知
道N次操作后数列中所有元素的和。他还要玩其他游戏,所以这个问题留给你解决。

输入

第一行一个整数N,然后有N行,每行三个正整数a、b、k。
N<=40000 , a、b、k<=10^9

输出

一个数,数列中所有元素的和

输入示例

  1.  

输出示例

  1.  

数据规模及约定

见“输入

题解

题目问的是最后的总和,所以对于每个元素我们只关心它经过所有包含它的操作后的值。每个操作 [a, b) -> k 建一个点 (a, b-1),权值为 k,则对于第 i 个数,找到点 (i, i) 左上方所有点的最大权值即为这个数最终的值。

看到这样的水题,而且数据范围又是 40000,感觉非常像带根号的算法,就忍不住写 kd 树了。

  1. #include <iostream>
  2. #include <cstdio>
  3. #include <algorithm>
  4. #include <cmath>
  5. #include <stack>
  6. #include <vector>
  7. #include <queue>
  8. #include <cstring>
  9. #include <string>
  10. #include <map>
  11. #include <set>
  12. using namespace std;
  13.  
  14. const int BufferSize = 1 << 16;
  15. char buffer[BufferSize], *Head, *Tail;
  16. inline char Getchar() {
  17. if(Head == Tail) {
  18. int l = fread(buffer, 1, BufferSize, stdin);
  19. Tail = (Head = buffer) + l;
  20. }
  21. return *Head++;
  22. }
  23. int read() {
  24. int x = 0, f = 1; char c = Getchar();
  25. while(!isdigit(c)){ if(c == '-') f = -1; c = Getchar(); }
  26. while(isdigit(c)){ x = x * 10 + c - '0'; c = Getchar(); }
  27. return x * f;
  28. }
  29.  
  30. #define maxn 40010
  31. #define oo 2147483647
  32. #define LL long long
  33. int n, lc[maxn], rc[maxn], root, Cur;
  34. struct Node {
  35. int x[2], mx[2], mn[2], val, maxv;
  36. bool operator < (const Node& t) const { return x[Cur] != t.x[Cur] ? x[Cur] < t.x[Cur] : x[Cur^1] < t.x[Cur^1]; }
  37. } ns[maxn], x;
  38.  
  39. void maintain(int o) {
  40. int l = lc[o], r = rc[o];
  41. for(int i = 0; i < 2; i++) {
  42. ns[o].mx[i] = max(max(ns[l].mx[i], ns[r].mx[i]), ns[o].x[i]);
  43. ns[o].mn[i] = min(min(ns[l].mn[i], ns[r].mn[i]), ns[o].x[i]);
  44. }
  45. ns[o].maxv = max(max(ns[l].maxv, ns[r].maxv), ns[o].val);
  46. return ;
  47. }
  48. void build(int& o, int L, int R, int cur) {
  49. if(L > R){ o = 0; return ; }
  50. int M = L + R >> 1; o = M;
  51. Cur = cur; nth_element(ns + L, ns + M, ns + R + 1);
  52. build(lc[o], L, M - 1, cur ^ 1); build(rc[o], M + 1, R, cur ^ 1);
  53. maintain(o);
  54. return ;
  55. }
  56. bool all(int o) { return ns[o].mx[0] <= x.x[0] && ns[o].mn[1] >= x.x[1]; }
  57. bool has(int o) { return ns[o].mn[0] <= x.x[0] && ns[o].mx[1] >= x.x[1]; }
  58. int query(int o) {
  59. if(!o) return 0;
  60. int l = lc[o], r = rc[o], ans = 0;
  61. if(ns[o].x[0] <= x.x[0] && ns[o].x[1] >= x.x[1]) ans = ns[o].val;
  62. if(ns[l].maxv > ns[r].maxv) {
  63. if(all(l)) ans = max(ans, ns[l].maxv);
  64. else if(has(l) && ns[l].maxv > ans) ans = max(ans, query(l));
  65. if(all(r)) ans = max(ans, ns[r].maxv);
  66. else if(has(r) && ns[r].maxv > ans) ans = max(ans, query(r));
  67. }
  68. else {
  69. if(all(r)) ans = max(ans, ns[r].maxv);
  70. else if(has(r) && ns[r].maxv > ans) ans = max(ans, query(r));
  71. if(all(l)) ans = max(ans, ns[l].maxv);
  72. else if(has(l) && ns[l].maxv > ans) ans = max(ans, query(l));
  73. }
  74. return ans;
  75. }
  76.  
  77. struct Cmd { int a, b, k; } cs[maxn];
  78. int cnt, num[maxn<<2], tp[maxn<<2];
  79. LL ans;
  80. int main() {
  81. ns[0].mx[0] = ns[0].mx[1] = -oo;
  82. ns[0].mn[0] = ns[0].mn[1] = oo;
  83. ns[0].maxv = -oo;
  84. n = read();
  85. for(int i = 1; i <= n; i++) {
  86. num[++cnt] = cs[i].a = read();
  87. num[++cnt] = cs[i].a + 1;
  88. num[++cnt] = cs[i].b = read() - 1;
  89. num[++cnt] = cs[i].b + 1;
  90. cs[i].k = read();
  91. }
  92. sort(num + 1, num + cnt + 1);
  93. cnt = unique(num + 1, num + cnt + 1) - num;
  94. // for(int i = 1; i <= cnt; i++) printf("%d ", num[i]); putchar('\n');
  95. for(int i = 1; i <= n; i++) {
  96. int x0 = lower_bound(num + 1, num + cnt + 1, cs[i].a) - num,
  97. x1 = lower_bound(num + 1, num + cnt + 1, cs[i].b) - num;
  98. ns[i].x[0] = x0; tp[x0] = 1;
  99. ns[i].x[1] = x1; tp[x1] = 1;
  100. ns[i].maxv = ns[i].val = cs[i].k;
  101. }
  102. for(int i = 1; i <= cnt; i++) if(!tp[i]) tp[i] = num[i+1] - num[i-1] - 1;
  103.  
  104. // for(int i = 1; i <= n; i++) printf("%d: %d %d %d\n", i, ns[i].x[0], ns[i].x[1], ns[i].val);
  105. build(root, 1, n, 0);
  106. // for(int i = 1; i <= n; i++) printf("%d: %d %d %d\n", i, ns[i].x[0], ns[i].x[1], ns[i].val);
  107. for(int i = 1; i <= cnt; i++) {
  108. x.x[0] = x.x[1] = i;
  109. int val = query(root);
  110. // printf("%d: %d %d\n", i, val, tp[i]);
  111. ans += (LL)tp[i] * (LL)val;
  112. }
  113.  
  114. printf("%lld\n", ans);
  115.  
  116. return 0;
  117. }

[BZOJ4636]蒟蒻的数列的更多相关文章

  1. [bzoj4636]蒟蒻的数列_线段树

    蒟蒻的数列 bzoj-4636 题目大意:给定一个序列,初始均为0.n次操作:每次讲一段区间中小于k的数都变成k.操作的最后询问全局和. 注释:$1\le n\le 4\cdot 10^4$. 想法: ...

  2. BZOJ4636: 蒟蒻的数列(动态开节点线段树)

    题意 题目链接 Sol 直接上动态开节点线段树 因为只有一次询问,所以中途不需要下传标记 #include<bits/stdc++.h> #define LL long long usin ...

  3. 【BZOJ4636】蒟蒻的数列 STL

    [BZOJ4636]蒟蒻的数列 Description 蒟蒻DCrusher不仅喜欢玩扑克,还喜欢研究数列 题目描述 DCrusher有一个数列,初始值均为0,他进行N次操作,每次将数列[a,b)这个 ...

  4. 【BZOJ-4636】蒟蒻的数列 动态开点线段树 ||(离散化) + 标记永久化

    4636: 蒟蒻的数列 Time Limit: 30 Sec  Memory Limit: 256 MBSubmit: 247  Solved: 113[Submit][Status][Discuss ...

  5. 【BZOJ】4636: 蒟蒻的数列

    4636: 蒟蒻的数列 Time Limit: 30 Sec  Memory Limit: 256 MBSubmit: 145  Solved: 71[Submit][Status][Discuss] ...

  6. BZOJ_4636_蒟蒻的数列_线段树+动态开点

    BZOJ_4636_蒟蒻的数列_线段树+动态开点 Description 蒟蒻DCrusher不仅喜欢玩扑克,还喜欢研究数列 题目描述 DCrusher有一个数列,初始值均为0,他进行N次操作,每次将 ...

  7. BZOJ 4636: 蒟蒻的数列 分块

    4636: 蒟蒻的数列 题目连接: http://www.lydsy.com/JudgeOnline/problem.php?id=4636 Description 蒟蒻DCrusher不仅喜欢玩扑克 ...

  8. 【bzoj4636】蒟蒻的数列 离散化+线段树

    原文地址:http://www.cnblogs.com/GXZlegend/p/6801379.html 题目描述 蒟蒻DCrusher不仅喜欢玩扑克,还喜欢研究数列 题目描述 DCrusher有一个 ...

  9. 【刷题】BZOJ 4636 蒟蒻的数列

    Description 蒟蒻DCrusher不仅喜欢玩扑克,还喜欢研究数列 题目描述 DCrusher有一个数列,初始值均为0,他进行N次操作,每次将数列[a,b)这个区间中所有比k小的数改为k,他想 ...

随机推荐

  1. express的session函数

    key:这个表示session返回来的cookie的键值, 我们整理一下哈: 这个是我们没有清缓存然后刷新了一下哈,对比的结果,发现session保存的数据中,只是expires这个改变了 { &qu ...

  2. jsonp的后台怎么返回去数据

  3. OC----简单的购物系统----

    今天下午OC上机考试,虽然考试的时候没写完, 但是课下写完了. main.m #import <Foundation/Foundation.h> #import "Shops.h ...

  4. Nginx下Redmine配置

    安装redmine依赖的所有ruby包 cd .. gem install bundler #注意是在网站根目录下执行 bundle install --without development tes ...

  5. DELETE和DELETE FROM有什么区别

    你如果只针对表进行删除,则一样. 但是如果需要联合其他表,则需要使用from 例如 delete tb1 from tb1 m where id in (select id from tb2) 我的习 ...

  6. Hession矩阵与牛顿迭代法

    1.求解方程. 并不是所有的方程都有求根公式,或者求根公式很复杂,导致求解困难.利用牛顿法,可以迭代求解. 原理是利用泰勒公式,在x0处展开,且展开到一阶,即f(x) = f(x0)+(x-x0)f' ...

  7. Spring JdbcTemplate 的使用与学习(转)

    紧接上一篇 (JdbcTemplate是线程安全的,因此可以配置一个简单的JdbcTemplate实例,将这个共享的实例注入到多个DAO类中.辅助的文档) Spring DAO支持 http://ww ...

  8. [NOIP2011] 提高组 洛谷P1312 Mayan游戏

    题目描述 Mayan puzzle是最近流行起来的一个游戏.游戏界面是一个 7 行5 列的棋盘,上面堆放着一些方块,方块不能悬空堆放,即方块必须放在最下面一行,或者放在其他方块之上.游戏通关是指在规定 ...

  9. pthread_kill

    别被名字吓到,pthread_kill可不是kill,而是向线程发送signal.还记得signal吗,大部分signal的默认动作是终止进程的运行,所以,我们才要用signal()去抓信号并加上处理 ...

  10. ActivityInfo taskAffinity

    通常在Manifest里面使用 <application android:icon="@drawable/icon" android:label="@string/ ...