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. 1197: [HNOI2006]花仙子的魔法 - BZOJ

    Description Input 包含两个整数,并用一个空格隔开,第一个整数表示实施魔法的次数m,第二个整数表示空间的维数n.其中,1≤m≤100,1≤n≤15. Output 仅包含一个整数,表示 ...

  2. 支付宝Unity

    原地址:http://blog.csdn.net/sgnyyy/article/details/20444627 说明:支付宝Android的SDK接入只有一个接口,付费. 1. Android代码的 ...

  3. 数据聚合 & 分组:新一代系统监控的核心功能

    遥想 2015 年 8 月 17 日,Cloud Insight 还在梳理功能原型,畅想 Cloud Insight 存在的意义:为什么阿里云用户需要使用 Cloud Insight 来加强管理. 而 ...

  4. 眼见为实(1):C++基本概念在编译器中的实现

    眼见为实(1):C++基本概念在编译器中的实现 对于C++对象模型,相信很多程序员都耳熟能详. 本文试图通过一个简单的例子演示一些C++基本概念在编译器中的实现,以期达到眼见为实的效果. 本文的演示程 ...

  5. dll的概念 dll导出变量 函数 类

    1. DLL的概念 DLL(Dynamic Linkable Library),动态链接库,可以向程序提供一些函数.变量或类.这些可以直接拿来使用. 静态链接库与动态链接库的区别:   (1)静态链接 ...

  6. HDU2697+DP

    dp[i][j]:从前i个中挑出某些且cost不超过j的最大val. dp[i][j]:应该有1到i-1的dp[k][j-?]来更新!! /* DP dp[i][j]:从前i个中挑出某些且cost不超 ...

  7. hibernate 数据行数统计 count(*)

    Hibernate关于sql中的count(*)数据统计: ①如果使用的是HQL: 直接在HQL中使用count(*)即可获取行数 Long count = (Long)HibernateUtil.g ...

  8. 使用头文件climits中的符号常量获知整型数据的表数范围---gyy整理

    在头文件climits(limits.h)以宏定义的方式定义了各种符号常量来表示各种整型类型表示数的范围,如int的最大最小值,long的最大最小值等. 符号常量 表示 CHAR_BIT char 的 ...

  9. Linux下安装Wine运行windows程序

    资料 首页 https://www.winehq.org/ 安装 https://www.winehq.org/download/ 教程 https://www.winehq.org/document ...

  10. 武汉北大青鸟解读2016年10大IT热门岗位

    武汉北大青鸟解读2016年10大IT热门岗位 2016年1月5日 13:37 北大青鸟 这是IT从业者的辉煌时代,IT行业的失业率正处在历史的低点,而且有的岗位——例如网络和安全工程师以及软件开发人员 ...