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

-----------------------------------------------------------------------------------------

#include<cstdio>
#include<cctype>
#include<cstring>
#include<algorithm>
 
using namespace std;
 
#define H(x) (lower_bound(H, H + n, x) - H + 1)
#define lb(x) ((x) & -(x))
 
const int maxn = 50009;
 
int N, Q, Pos;
int H[maxn], n;
 
inline int getint() {
char c = getchar();
int ret = 0, f = 1;
for(; !isdigit(c); c = getchar()) if(c == '-') f = 0;
for(; isdigit(c); c = getchar()) ret = ret * 10 - '0' + c;
return f ? ret : -ret;
}
 
struct O {
int t, l, r, v;
inline void Read() {
t = getint(), l = getint(), r = getint(), v = getint();
}
} o[maxn];
 
struct Node {
Node *lc, *rc;
int v;
} pool[maxn * 400], *pt, *Null, *A[maxn], *B[maxn];
 
void Init_sgt() {
(pt = pool)->v = 0;
pt->lc = pt->rc = pt;
Null = pt++;
}
 
Node* Modify(Node* t, int l, int r, int ad) {
Node* p = pt++;
p->v = t->v + ad;
if(l != r) {
int m = (l + r) >> 1;
if(Pos <= m) {
p->lc = Modify(t->lc, l, m, ad);
p->rc = t->rc;
} else {
p->lc = t->lc;
p->rc = Modify(t->rc, m + 1, r, ad);
}
}
return p;
}
 
Node *L0[20], *L1[20], *L[20];
Node *R0[20], *R1[20];
 
void Work() {
Init_sgt();
int ln, rn, sn;
for(int i = 0; i <= N; i++) A[i] = B[i] = Null;
for(int i = 0; i < Q; i++) if(o[i].t == 1) {
Pos = H(o[i].v);
for(int x = o[i].l; x <= N; x += lb(x)) {
A[x] = Modify(A[x], 1, n, 1);
B[x] = Modify(B[x], 1, n, o[i].l - 1);
}
for(int x = o[i].r + 1; x <= N; x += lb(x)) {
A[x] = Modify(A[x], 1, n, -1);
B[x] = Modify(B[x], 1, n, -o[i].r);
}
} else {
ln = rn = sn = 0;
for(int x = o[i].l; x; x -= lb(x)) L[sn++] = A[x];
for(int x = o[i].l; x; x -= lb(x))
L0[ln] = A[x], R1[ln++] = B[x];
for(int x = o[i].r; x; x -= lb(x))
R0[rn] = A[x], L1[rn++] = B[x];
int l = 1, r = n, len = o[i].r - o[i].l + 1;
while(l < r) {
int m = (l + r) >> 1, cnt = 0;
for(int x = 0; x < sn; x++) cnt += L[x]->rc->v * len;
for(int x = 0; x < ln; x++)
cnt += R1[x]->rc->v - o[i].r * L0[x]->rc->v;
for(int x = 0; x < rn; x++)
cnt += o[i].r * R0[x]->rc->v - L1[x]->rc->v;
if(cnt >= o[i].v) {
for(int x = 0; x < sn; x++) L[x] = L[x]->rc;
for(int x = 0; x < ln; x++)
R1[x] = R1[x]->rc, L0[x] = L0[x]->rc;
for(int x = 0; x < rn; x++)
R0[x] = R0[x]->rc, L1[x] = L1[x]->rc;
l = m + 1;
} else {
o[i].v -= cnt;
for(int x = 0; x < sn; x++) L[x] = L[x]->lc;
for(int x = 0; x < ln; x++)
R1[x] = R1[x]->lc, L0[x] = L0[x]->lc;
for(int x = 0; x < rn; x++)
R0[x] = R0[x]->lc, L1[x] = L1[x]->lc;
r = m;
}
}
printf("%d\n", H[l - 1]);
}
}
 
void Init() {
N = getint(), Q = getint();
n = 0;
for(int i = 0; i < Q; i++) {
o[i].Read();
if(o[i].t == 1) H[n++] = o[i].v;
}
sort(H, H + n);
n = unique(H, H + n) - H;
}
 
int main() {
Init();
Work();
return 0;
}

-----------------------------------------------------------------------------------------

3110: [Zjoi2013]K大数查询

Time Limit: 20 Sec  Memory Limit: 512 MB
Submit: 2921  Solved: 1247
[Submit][Status][Discuss]

Description

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

Input

第一行N,M
接下来M行,每行形如1 a b c或2 a b c

Output

输出每个询问的结果

Sample Input

2 5
1 1 2 1
1 1 2 2
2 1 1 2
2 1 1 1
2 1 2 3

Sample Output

1
2
1

HINT

【样例说明】

第一个操作 后位置 1 的数只有 1 , 位置 2 的数也只有 1 。 第二个操作 后位置 1

的数有 1 、 2 ,位置 2 的数也有 1 、 2 。 第三次询问 位置 1 到位置 1 第 2 大的数 是

1 。 第四次询问 位置 1 到位置 1 第 1 大的数是 2 。 第五次询问 位置 1 到位置 2 第 3

大的数是 1 。‍

N,M<=50000,N,M<=50000

a<=b<=N

1操作中abs(c)<=N

2操作中abs(c)<=Maxlongint

Source

BZOJ 3110: [Zjoi2013]K大数查询( 树状数组套主席树 )的更多相关文章

  1. BZOJ 3196 Tyvj 1730 二逼平衡树 ——树状数组套主席树

    [题目分析] 听说是树套树.(雾) 怒写树状数组套主席树,然后就Rank1了.23333 单点修改,区间查询+k大数查询=树状数组套主席树. [代码] #include <cstdio> ...

  2. BZOJ 1901 Zju2112 Dynamic Rankings ——树状数组套主席树

    [题目分析] BZOJ这个题目抄的挺霸气. 主席树是第一时间想到的,但是修改又很麻烦. 看了别人的题解,原来还是可以用均摊的思想,用树状数组套主席树. 学到了新的姿势,2333o(* ̄▽ ̄*)ブ [代 ...

  3. ZOJ 2112 Dynamic Rankings(树状数组套主席树 可修改区间第k小)题解

    题意:求区间第k小,节点可修改 思路:如果直接用静态第k小去做,显然我更改一个节点后,后面的树都要改,这个复杂度太高.那么我们想到树状数组思路,树状数组是求前缀和,那么我们可以用树状数组套主席树,求出 ...

  4. BZOJ 2141 排队(树状数组套主席树)

    解法很多的题,可以块套树状数组,可以线段树套平衡树.我用的是树状数组套主席树. 题意:给出一段数列,m次操作,每次操作是交换两个位置的数,求每次操作后的逆序对数.(n,m<=2e4). 对于没有 ...

  5. BZOJ_3196_Tyvj 1730 二逼平衡树_树状数组套主席树

    BZOJ_3196_Tyvj 1730 二逼平衡树_树状数组套主席树 Description 您需要写一种数据结构(可参考题目标题),来维护一个有序数列,其中需要提供以下操作: 1.查询k在区间内的排 ...

  6. [COGS257]动态排名系统 树状数组套主席树

    257. 动态排名系统 时间限制:5 s   内存限制:512 MB [问题描述]给定一个长度为N的已知序列A[i](1<=i<=N),要求维护这个序列,能够支持以下两种操作:1.查询A[ ...

  7. [bzoj3196][Tyvj1730]二逼平衡树_树套树_位置线段树套非旋转Treap/树状数组套主席树/权值线段树套位置线段树

    二逼平衡树 bzoj-3196 Tyvj-1730 题目大意:请写出一个维护序列的数据结构支持:查询给定权值排名:查询区间k小值:单点修改:查询区间内定值前驱:查询区间内定值后继. 注释:$1\le ...

  8. P2617 Dynamic Rankings(树状数组套主席树)

    P2617 Dynamic Rankings 单点修改,区间查询第k大 当然是无脑树套树了~ 树状数组套主席树就好辣 #include<iostream> #include<cstd ...

  9. 洛谷P3759 [TJOI2017]不勤劳的图书管理员 【树状数组套主席树】

    题目链接 洛谷P3759 题解 树状数组套主席树板题 #include<algorithm> #include<iostream> #include<cstring> ...

  10. Codeforces Round #404 (Div. 2) E. Anton and Permutation(树状数组套主席树 求出指定数的排名)

    E. Anton and Permutation time limit per test 4 seconds memory limit per test 512 megabytes input sta ...

随机推荐

  1. C# 使用XmlDocument类对XML文档进行操作

    原创地址:http://www.cnblogs.com/jfzhu/archive/2012/11/19/2778098.html 转载请注明出处 W3C制定了XML DOM标准.很多编程语言中多提供 ...

  2. 【每天一个Linux命令】14. Linux中locate命令的用法

    命令用途 locate 让使用者可以很快速的搜寻档案系统内是否有指定的档案. 其方法是先建立一个包括系统内所有档案名称及路径的数据库,之后当寻找时就只需查询这个数据库,而不必实际深入档案系统之中了. ...

  3. Java 可中断线程

    PART.1 无法中断的线程 一个无法中断的线程的例子. public class UninterruptableThread { @SuppressWarnings("deprecatio ...

  4. jquery单页网站导航插件One Page Nav

    这是一个轻量级的jQuery的单页网站导航插件.增加了单击后平滑滚动导航和当你浏览不同的部分时自动选择正确的导航项. changeHash: false, 改变当用户单击导航,就改变changeHas ...

  5. box-shadow属性

    一.定义和用法 box-shadow属性 向框添加一个或多个阴影. 二.语法 box-shadow: h-shadow v-shadow blur spread color inset; h-shad ...

  6. 获取iOS设备属性

    通过使用UIDevice: [[UIDevice currentDevice] systemName]; [[UIDevice currentDevice] systemVersion];//os v ...

  7. U3D学习使用笔记(三)

    1.对动画进行播放和暂停(从初始位置) (1).老版动画系统Animation 暂停 an["Take 001"].time = 0f; an["Take 001&quo ...

  8. linux可执行文件目录的区别

    /bin./sbin./usr/bin./usr/sbin目录的区别 在linux下我们经常用到的四个应用程序的目录是/bin./sbin./usr/bin./usr/sbin .而四者存放的文件一般 ...

  9. Windows Server 2008 Enterprise使用12G内存

    开启PAE选项,用以下命令解决这个问题: 1.开始运行cmd2.输入 BCDEdit /set PAE forceenable 后回车3.重起系统显示12GB内存,一切正常

  10. windows迁移linux问题集锦[ZZ]

    http://blog.csdn.net/m_star_jy_sy/article/details/8482202 1)‘_wcsicmp’在此作用域中尚未声明 #ifdef WIN32#define ...