BZOJ 3110

很早就想写的试炼场题。

不会整体二分啊呜呜呜,只能写写树套树。

有一个trick就是外层使用一个权值线段树,把位置作为下标的线段树放在内层,这样子的话我们在查询$k$大的时候就可以直接在外层线段树上一边走一边二分。

注意我们查询的是第$k$大不是第$k$小,所以我们在走的时候要观察右子树的权值和$k$的关系。

内层可以动态开点防mle,注意在打标记下传的时候要先给左右儿子赋值。

挺卡常的。

时间复杂度$O(nlog^2n)$。

Code:

#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;
typedef long long ll; const int N = 5e4 + ; int n, qn, mn, tot = ;
ll val[N]; struct Querys {
int type, l, r;
ll k;
} q[N]; template <typename T>
inline void read(T &X) {
X = ; char ch = ; T op = ;
for(; ch > ''|| ch < ''; ch = getchar())
if(ch == '-') op = -;
for(; ch >= '' && ch <= ''; ch = getchar())
X = (X << ) + (X << ) + ch - ;
X *= op;
} namespace SegT {
struct Node {
int lc, rc, tag;
ll sum;
} s[N * ]; int root[N << ], nodeCnt = ; #define lc(p) s[p].lc
#define rc(p) s[p].rc
#define sum(p) s[p].sum
#define tag(p) s[p].tag
#define mid ((l + r) >> 1) inline void up(int p) {
if(!p) return;
sum(p) = sum(lc(p)) + sum(rc(p));
} inline void down(int p, int l, int r) {
if(!tag(p)) return;
if(!lc(p)) lc(p) = ++nodeCnt;
if(!rc(p)) rc(p) = ++nodeCnt;
sum(lc(p)) += 1LL * tag(p) * (mid - l + ), tag(lc(p)) += tag(p);
sum(rc(p)) += 1LL * tag(p) * (r - mid), tag(rc(p)) += tag(p);
tag(p) = ;
} void ins(int &p, int l, int r, int x, int y) {
if(!p) p = ++nodeCnt;
if(x <= l && y >= r) {
++tag(p);
sum(p) += 1LL * (r - l + );
return;
} down(p, l, r);
if(x <= mid) ins(lc(p), l, mid, x, y);
if(y > mid) ins(rc(p), mid + , r, x, y);
up(p);
} ll getSum(int p, int l, int r, int x, int y) {
if(!p) return 0LL;
if(x <= l && y >= r) return sum(p); down(p, l, r); ll res = 0LL;
if(x <= mid) res += getSum(lc(p), l, mid, x, y);
if(y > mid) res += getSum(rc(p), mid + , r, x, y);
return res;
} void modify(int p, int l, int r, int x, int y, int v) {
ins(root[p], , n, x, y);
if(l == r) return; if(v <= mid) modify(p << , l, mid, x, y, v);
else modify(p << | , mid + , r, x, y, v);
} int query(int p, int l, int r, int x, int y, ll k) {
if(l == r) return l; ll now = getSum(root[p << | ], , n, x, y);
if(now >= k) return query(p << | , mid + , r, x, y, k);
else return query(p << , l, mid, x, y, k - now);
} } using namespace SegT; int main() {
read(n), read(qn);
for(int i = ; i <= qn; i++) {
read(q[i].type), read(q[i].l), read(q[i].r), read(q[i].k);
if(q[i].type == ) val[++tot] = q[i].k;
} sort(val + , val + tot + );
tot = unique(val + , val + + tot) - val - ;
mn = tot; for(int i = ; i <= qn; i++) {
if(q[i].type == ) {
int v = lower_bound(val + , val + + tot, q[i].k) - val;
modify(, , mn, q[i].l, q[i].r, v);
} else printf("%lld\n", val[query(, , mn, q[i].l, q[i].r, q[i].k)]);
} return ;
}

Luogu 3332 [ZJOI2013]K大数查询的更多相关文章

  1. BZOJ 3110: [Zjoi2013]K大数查询 [树套树]

    3110: [Zjoi2013]K大数查询 Time Limit: 20 Sec  Memory Limit: 512 MBSubmit: 6050  Solved: 2007[Submit][Sta ...

  2. 树套树专题——bzoj 3110: [Zjoi2013] K大数查询 &amp; 3236 [Ahoi2013] 作业 题解

    [原题1] 3110: [Zjoi2013]K大数查询 Time Limit: 20 Sec  Memory Limit: 512 MB Submit: 978  Solved: 476 Descri ...

  3. bzoj 3110: [Zjoi2013]K大数查询 树状数组套线段树

    3110: [Zjoi2013]K大数查询 Time Limit: 20 Sec  Memory Limit: 512 MBSubmit: 1384  Solved: 629[Submit][Stat ...

  4. BZOJ 3110: [Zjoi2013]K大数查询( 树状数组套主席树 )

    BIT+(可持久化)权值线段树, 用到了BIT的差分技巧. 时间复杂度O(Nlog^2(N)) ---------------------------------------------------- ...

  5. BZOJ 3110([Zjoi2013]K大数查询-区间第k大[段修改,在线]-树状数组套函数式线段树)

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

  6. BZOJ_3110_[Zjoi2013]K大数查询_整体二分+树状数组

    BZOJ_3110_[Zjoi2013]K大数查询_整体二分+树状数组 Description 有N个位置,M个操作.操作有两种,每次操作如果是1 a b c的形式表示在第a个位置到第b个位置,每个位 ...

  7. P3332 [ZJOI2013]K大数查询(线段树套线段树+标记永久化)

    P3332 [ZJOI2013]K大数查询 权值线段树套区间线段树 把插入的值离散化一下开个线段树 蓝后每个节点开个线段树,维护一下每个数出现的区间和次数 为了防止MLE动态开点就好辣 重点是标记永久 ...

  8. 【BZOJ3110】【LG3332】[ZJOI2013]K大数查询

    [BZOJ3110][LG3332][ZJOI2013]K大数查询 题面 洛谷 BZOJ 题解 和普通的整体分治差不多 用线段树维护一下每个查询区间内大于每次二分的值\(mid\)的值即可 然后再按套 ...

  9. 3110: [Zjoi2013]K大数查询

    3110: [Zjoi2013]K大数查询 https://lydsy.com/JudgeOnline/problem.php?id=3110 分析: 整体二分+线段树. 两种操作:区间加入一个数,区 ...

随机推荐

  1. Python文件练习

    练习内容: 使用Python管理ini文件:实现查询,添加,删除,保存操作. 练习目的: 1.掌握文件基本操作 2.认识ini文件 3.了解ConfigParser: ini配置文件格式: 节:[se ...

  2. java入门学习(1)一简介及其基础特点

    分类: java基础 1.为什么java如此流行,为什么历史选择了它? 因为它拥有全新的编程思想,更接近人们的语言习惯,由于其编译器把代码编译成字节码,然后再不同的平台上运行分别用不同的虚拟机去解释字 ...

  3. php实现word在线浏览功能。

    http://laoniangke.com/php/2012/10/08/php-doc-webview.html

  4. I.MX6 dts 在哪里、怎么编译

    /************************************************************************ * I.MX6 DTS 在哪里.怎么编译 * 说明: ...

  5. RedHat 6.8 打开vga之后Login界面花屏

    /******************************************************************* * RedHat 6.8 打开vga之后Login界面花屏 * ...

  6. memcached数据库

    Python-memcached的基本使用

  7. loj#6566. 月之都的密码

    搜交互题搜到的... 竟然还有这么水的交互题,赶紧过了再说 交互库里有一个 $[1,n]$ 到 $[1,n]$ 的双射 你可以调用 $encode(k,a[])$ 询问左边的一个大小为 $k$ 的集合 ...

  8. Mybatis_generator自动化生成代码

    1.Run as 2.ok

  9. volatile关键字及内存可见性

    先看一段代码: package com.java.juc; public class TestVolatile { public static void main(String[] args) { T ...

  10. 如何卸载Python通过setup.py安装的模块

    0,pip uninstall  xxxx     1.找到egg sudo easy_install -m BitVector .... Using /usr/local/lib/python2./ ...