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

【思路】

线段树套线段树

里面的线段树基于区间,外面的线段树基于权值。我们就可以知道权值在[a,b]内且位置位于[c,d]内的数有多少个。

Add操作:在外面的线段树中找到c,将路径上经过的所有点对应的内层线段树区间[a,b]加1。

Query操作:在外面的线段树中通过询问对应的内层线段树结点的多少进行类似平衡树的转移。

线段树动态分配节点。

求第k大。。。

【代码】

 #include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
#define FOR(a,b,c) for(int a=(b);a<=(c);a++)
using namespace std; typedef long long ll;
const int N = +;
const int M = +; struct Tnode{
int lc,rc,add,sum;
Tnode(){}
}T[M]; int read() {
char c=getchar();
int f=,x=;
while(!isdigit(c)) {
if(c=='-') f=-; c=getchar();
}
while(isdigit(c))
x=x*+c-'',c=getchar();
return x*f;
} int n,m,sz;
int rt[M]; void pushdown(int u,int l,int r)
{
if(!T[u].add || l==r) return ;
if(!T[u].lc) T[u].lc=++sz;
if(!T[u].rc) T[u].rc=++sz;
int v=T[u].add , mid=(l+r)>>;
T[T[u].lc].add+=v;
T[T[u].rc].add+=v;
T[T[u].lc].sum+=v*(mid-l+);
T[T[u].rc].sum+=v*(r-mid);
T[u].add=;
}
void update(int &u,int l,int r,int L,int R)
{
if(!u) u=++sz;
pushdown(u,l,r);
if(L<=l&&r<=R) {
T[u].add++;
T[u].sum+=r-l+;
} else {
int mid=(l+r)>>;
if(L<=mid) update(T[u].lc,l,mid,L,R);
if(mid<R ) update(T[u].rc,mid+,r,L,R);
T[u].sum=T[T[u].lc].sum+T[T[u].rc].sum;
}
}
int query(int u,int l,int r,int L,int R)
{
if(!u) return ;
pushdown(u,l,r);
if(L<=l&&r<=R) return T[u].sum;
else {
int mid=(l+r)>>,ans=;
if(L<=mid) ans+=query(T[u].lc,l,mid,L,R);
if(mid<R ) ans+=query(T[u].rc,mid+,r,L,R);
return ans;
}
}
void change(int a,int b,int c)
{
int u=,l=,r=n;
while(l!=r) {
int mid=(l+r)>>;
update(rt[u],,n,a,b);
if(c<=mid) r=mid,u=u<<;
else l=mid+,u=u<<|;
}
update(rt[u],,n,a,b);
}
int query(int a,int b,int c)
{
int u=,l=,r=n;
while(l!=r) {
int mid=(l+r)>>;
int t=query(rt[u<<],,n,a,b);
if(c<=t) r=mid,u=u<<;
else l=mid+,u=u<<|,c-=t;
}
return l;
} int main()
{
//freopen("in.in","r",stdin);
//freopen("out.out","w",stdout);
n=read(),m=read();
int op,a,b,c;
FOR(i,,m) {
op=read(),a=read(),b=read(),c=read();
if(op==) {
change(a,b,n-c+);
} else {
printf("%d\n",n-query(a,b,c)+);
}
}
return ;
}

bzoj 3110 [Zjoi2013]K大数查询(树套树)的更多相关文章

  1. BZOJ.3110.[ZJOI2013]K大数查询(整体二分 树状数组/线段树)

    题目链接 BZOJ 洛谷 整体二分求的是第K小(利用树状数组).求第K大可以转为求第\(n-K+1\)小,但是这样好像得求一个\(n\). 注意到所有数的绝对值\(\leq N\),将所有数的大小关系 ...

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

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

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

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

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

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

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

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

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

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

  7. BZOJ 3110 [Zjoi2013]K大数查询(整体二分)

    3110: [Zjoi2013]K大数查询 Time Limit: 20 Sec  Memory Limit: 512 MBSubmit: 11654  Solved: 3505[Submit][St ...

  8. bzoj 3110 [Zjoi2013]K大数查询【树套树||整体二分】

    树套树: 约等于是个暴力了.以区间线段树的方式开一棵权值线段树,在权值线段树的每一个点上以动态开点的方式开一棵区间线段树. 结果非常惨烈(时限20s) #include<iostream> ...

  9. BZOJ 3110 [Zjoi2013]K大数查询 ——树套树

    [题目分析] 外层区间线段树,内层是动态开点的权值线段树. SY神犇说树套树注重的是内外层的数据结构的选择问题,果然很重要啊. 动态开点的实现方法很好. [代码] #include <cstdi ...

  10. BZOJ 3110: [Zjoi2013]K大数查询 [整体二分]

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

随机推荐

  1. Mybatis 示例之 SelectKey(转)

    参考:http://blog.csdn.net/isea533/article/details/21153791 SelectKey在Mybatis中是为了解决Insert数据时不支持主键自动生成的问 ...

  2. js获取节点

    demo1: <!-- <div id="test" v="1">你好</div> --> // console.log(t ...

  3. [转载]MongoDB查询优化原则

    .在查询条件.排序条件.统计条件的字段上选择创建索引,可以显著提高查询效率. .用$or时把匹配最 多 结果的条件放在最前面,用$and时把匹配最 少 结果的条件放在最前面. .使用limit()限定 ...

  4. cf 357C

    比赛的时候纯暴力超时了  看了别人的代码  set容器类做的   stl里还是有很多好东西的 /**************************************************** ...

  5. 【C++基础】关键字static 局部变量

    1.局部变量 static局部变量和普通局部变量有什么区别:static局部变量只被初始化一次,下一次依据上一次结果值: int test(int j){ static int i=10; i=i+j ...

  6. C++:在程序中获取全球唯一标识号(GUID或UUID)

    Windows:使用CoCreateGuid函数(GUID) #include <objbase.h> #include <stdio.h> #define GUID_LEN  ...

  7. Codeforces Round #243 (Div. 2) A~C

    题目链接 A. Sereja and Mugs time limit per test:1 secondmemory limit per test:256 megabytesinput:standar ...

  8. QString和char字符数组之间的转换(QTextCodec.toUnicode方法,特别注意\0的问题)

    How can I convert a QString to char* and vice versa ?(trolltech) Answer:In order to convert a QStrin ...

  9. SQL Server常见问题总结

    写在前面 在QQ群,微信群,论坛中经常帮助使用SQL Server数据库的朋友解决问题,但是有一些最常见最基本的问题,每天都有人问,回答多了也不想再解答了,索性把这些问题整理一下,再有人问到直接发链接 ...

  10. linux应用程序问题

    ---- 1 ----