3110: [Zjoi2013]K大数查询

https://lydsy.com/JudgeOnline/problem.php?id=3110

分析:

  整体二分+线段树。

  两种操作:区间加入一个数,区间询问第k大值。

  如果只有一种操作,我们可以二分答案x,然后把大于x的都加入到线段树中去(区间[l,r]整体+1),然后查询这次询问的区间有多少数(区间[l,r]求和)。

  多种操作的话整体二分就行了,注意到有时间顺序,所以可以按照时间顺序加入和查询。

  注意一下要开longlong。

代码:

 1 #include<cstdio>
 2 #include<algorithm>
 3 #include<cstring>
 4 #include<iostream>
 5 #include<cmath>
 6 #include<cctype>
 7 #include<set>
 8 #include<queue>
 9 #include<vector>
10 #include<map>
11 #define Root 1, n, 1
12 #define lson l, mid, rt << 1
13 #define rson mid + 1, r, rt << 1 | 1
14 using namespace std;
15 typedef long long LL;
16
17 inline int read() {
18     int x=0,f=1;char ch=getchar();for(;!isdigit(ch);ch=getchar())if(ch=='-')f=-1;
19     for(;isdigit(ch);ch=getchar())x=x*10+ch-'0';return x*f;
20 }
21
22 const int N = 50005;
23
24 int ans[N], n, m;
25 struct Que{
26     int ty, l, r, v, id;
27     bool operator < (const Que &A) const {
28         return id < A.id;
29     }
30 }A[N], tl[N], tr[N];
31 struct SegmentTree{
32     LL sum[N << 2], tag[N << 2];
33     void pushup(int rt) { sum[rt] = sum[rt << 1] + sum[rt << 1 | 1]; }
34     void pushdown(int rt,int len) {
35         sum[rt << 1] += 1ll * (len - len / 2) * tag[rt];
36         sum[rt << 1 | 1] += 1ll * (len / 2) * tag[rt];
37         tag[rt << 1] += tag[rt];
38         tag[rt << 1 | 1] += tag[rt];
39         tag[rt] = 0;
40     }
41     void update(int l,int r,int rt,int L,int R,int v) {
42         if (L <= l && r <= R) {
43             tag[rt] += v, sum[rt] += (r - l + 1) * v; return ;
44         }
45         if (tag[rt]) pushdown(rt, r - l + 1);
46         int mid = (l + r) >> 1;
47         if (L <= mid) update(lson, L, R, v);
48         if (R > mid) update(rson, L, R, v);
49         pushup(rt);
50     }
51     LL query(int l,int r,int rt,int L,int R) {
52         if (L <= l && r <= R) return sum[rt];
53         if (tag[rt]) pushdown(rt, r - l + 1);
54         int mid = (l + r) >> 1; LL res = 0;
55         if (L <= mid) res += query(lson, L, R);
56         if (R > mid) res += query(rson, L, R);
57         return res;
58     }
59 }T;
60
61 void solve(int l,int r,int Head,int Tail) {
62     if (Head > Tail) return ;
63     if (l == r) {
64         for (int i = Head; i <= Tail; ++i)
65             if (A[i].ty == 2) ans[A[i].id] = l;
66         return ;
67     }
68     int mid = (l + r + 1) >> 1, cl = 0, cr = 0;
69     for (int i = Head; i <= Tail; ++i) {
70         if (A[i].ty == 1) {
71             if (A[i].v >= mid) T.update(Root, A[i].l, A[i].r, 1), tr[++cr] = A[i];
72             else tl[++cl] = A[i];
73         }
74         else {
75             LL t = T.query(Root, A[i].l, A[i].r);
76             if (t >= A[i].v) tr[++cr] = A[i];
77             else A[i].v -= t, tl[++cl] = A[i];
78         }
79     }
80     for (int i = Head; i <= Tail; ++i) if (A[i].ty == 1 && A[i].v >= mid) T.update(Root, A[i].l, A[i].r, -1);
81     for (int i = 1; i <= cl; ++i) A[i + Head - 1] = tl[i];
82     for (int i = 1; i <= cr; ++i) A[i + Head + cl - 1] = tr[i];
83     solve(l, mid - 1, Head, Head + cl - 1);
84     solve(mid, r, Head + cl, Tail);
85 }
86 int main() {
87     n = read(), m = read(); int Q = 0;
88     for (int i = 1; i <= m; ++i) {
89         A[i].ty = read(), A[i].l = read(), A[i].r = read(), A[i].v = read(), A[i].id = 0;
90         if (A[i].ty == 2) A[i].id = ++Q;
91     }
92     solve(0, n, 1, m);
93     for (int i = 1; i <= Q; ++i) printf("%d\n",ans[i]);
94     return 0;
95 }

转载于:https://www.cnblogs.com/mjtcn/p/10081790.html

3110: [Zjoi2013]K大数查询相关推荐

  1. bzoj 3110: [Zjoi2013]K大数查询(树套树)

    树套树: 本质:一棵树的每个节点套着另一棵树 通常时间复杂度:O(nlog²n) 空间复杂度:因为树的大小是nlogn,而每个节点又有一棵nlogn的树,所以最大空间复杂度为O(n²log²) 但事实 ...

  2. bzoj:3110: [Zjoi2013]K大数查询

    Description 有N个位置,M个操作.操作有两种,每次操作如果是1 a b c的形式表示在第a个位置到第b个位置,每个位置加入一个数c 如果是2 a b c形式,表示询问从第a个位置到第b个位 ...

  3. [bzoj 3110] [ZJOI2013] K大数查询

    题目链接: https://www.lydsy.com/JudgeOnline/problem.php?id=3110 题目: 有N个位置,M个操作.操作有两种,每次操作如果是: 1 a b c:表示 ...

  4. bzoj3110 [Zjoi2013]K大数查询

    3110: [Zjoi2013]K大数查询 Time Limit: 20 Sec  Memory Limit: 512 MB Submit: 10703  Solved: 3209 [Submit][ ...

  5. [BZOJ3110] [Zjoi2013]K大数查询

    3110: [Zjoi2013]K大数查询 Time Limit: 20 Sec  Memory Limit: 512 MB Submit: 9208  Solved: 2737 [Submit][S ...

  6. 洛谷 P3332 [ZJOI2013]K大数查询 解题报告

    P3332 [ZJOI2013]K大数查询 题目描述 有\(N\)个位置,\(M\)个操作.操作有两种,每次操作如果是\(\tt{1\ a\ b\ c}\)的形式表示在第\(a\)个位置到第\(b\) ...

  7. BZOJ3110: [Zjoi2013]K大数查询

    BZOJ3110: [Zjoi2013]K大数查询 Description 有N个位置,M个操作. 操作有两种,每次操作如果是1 a b c的形式表示在第a个位置到第b个位置,每个位置加入一个数c 如 ...

  8. P3332 [ZJOI2013]K大数查询(整体二分做法)

    P3332 [ZJOI2013]K大数查询 题意: 题解: 利用整体二分来做,这个题和P3834 [模板]可持久化线段树 2的区别在于本题的修改是区间修改,所以将里面的树状数组改成线段树就行,区间修改 ...

  9. bzoj3110: [Zjoi2013]K大数查询 【树套树,标记永久化】

    //========================== 蒟蒻Macaulish:http://www.cnblogs.com/Macaulish/  转载要声明! //=============== ...

最新文章

  1. 五子棋html游戏代码与算法介绍
  2. python交互窗口怎么才能不连着上一个程序_python实现启动一个外部程序,并且不阻塞当前进程...
  3. 解决Ubuntu无法进行SSH连接的问题(以及如何使用SSH)
  4. 对象属性之间的相互赋值
  5. 应对“反洗钱”,银丰新融反洗钱自主监测系统为机构保驾护航
  6. shell连接远程mongodb数据库
  7. FairMOT: On the Fairness of Detection and Re-Identification in Multiple Object Tracking 效果展示
  8. Srs之Clion编译
  9. 搭建Android的开发环境
  10. 2017服务器cpu性能排行,桌面CPU性能排行 CPU天梯图2017年7月最新版
  11. 搭窝---开篇语---爆笑语录
  12. @Value 注解用法
  13. 苏宁 OLAP 引擎发展之路
  14. 4.文本分类——textRNN模型
  15. 程序员常用工具网站汇总(一)
  16. 未能从程序集“mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089”中加载类型“System.Coll
  17. 不相信九江大桥事故专家鉴定的五大理由
  18. PyCharm 社区版(Community)能不能商用?
  19. python图片镜像反转
  20. 查找数组中的所有重复项

热门文章

  1. python连接池框架_Python中的连接池是非常重要的!神级程序员详解!
  2. gps频率范围_以GPS为例讲解射频接收阻抗匹配的过程
  3. qt种qdebug字符串_qDebug用法及中文乱码解决
  4. 惠普光影精灵拆机换屏幕_聊聊惠普游戏本大军的“先遣部队”
  5. 如何编写字符设备驱动
  6. 基于softmax的文本多分类模型代码实现
  7. Java实现Redis的消息订阅和发布
  8. Pytorch:初始化
  9. EXCEL 两列名字 如何快速查看缺少了哪些人名
  10. 网络编程---tcp/udp协议