bzoj 3110 [Zjoi2013]K大数查询(树套树)
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
1 1 2 1
1 1 2 2
2 1 1 2
2 1 1 1
2 1 2 3
Sample Output
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大数查询(树套树)的更多相关文章
- BZOJ.3110.[ZJOI2013]K大数查询(整体二分 树状数组/线段树)
题目链接 BZOJ 洛谷 整体二分求的是第K小(利用树状数组).求第K大可以转为求第\(n-K+1\)小,但是这样好像得求一个\(n\). 注意到所有数的绝对值\(\leq N\),将所有数的大小关系 ...
- BZOJ 3110: [Zjoi2013]K大数查询 [树套树]
3110: [Zjoi2013]K大数查询 Time Limit: 20 Sec Memory Limit: 512 MBSubmit: 6050 Solved: 2007[Submit][Sta ...
- 树套树专题——bzoj 3110: [Zjoi2013] K大数查询 & 3236 [Ahoi2013] 作业 题解
[原题1] 3110: [Zjoi2013]K大数查询 Time Limit: 20 Sec Memory Limit: 512 MB Submit: 978 Solved: 476 Descri ...
- bzoj 3110: [Zjoi2013]K大数查询 树状数组套线段树
3110: [Zjoi2013]K大数查询 Time Limit: 20 Sec Memory Limit: 512 MBSubmit: 1384 Solved: 629[Submit][Stat ...
- BZOJ 3110: [Zjoi2013]K大数查询( 树状数组套主席树 )
BIT+(可持久化)权值线段树, 用到了BIT的差分技巧. 时间复杂度O(Nlog^2(N)) ---------------------------------------------------- ...
- BZOJ 3110([Zjoi2013]K大数查询-区间第k大[段修改,在线]-树状数组套函数式线段树)
3110: [Zjoi2013]K大数查询 Time Limit: 20 Sec Memory Limit: 512 MB Submit: 418 Solved: 235 [ Submit][ ...
- BZOJ 3110 [Zjoi2013]K大数查询(整体二分)
3110: [Zjoi2013]K大数查询 Time Limit: 20 Sec Memory Limit: 512 MBSubmit: 11654 Solved: 3505[Submit][St ...
- bzoj 3110 [Zjoi2013]K大数查询【树套树||整体二分】
树套树: 约等于是个暴力了.以区间线段树的方式开一棵权值线段树,在权值线段树的每一个点上以动态开点的方式开一棵区间线段树. 结果非常惨烈(时限20s) #include<iostream> ...
- BZOJ 3110 [Zjoi2013]K大数查询 ——树套树
[题目分析] 外层区间线段树,内层是动态开点的权值线段树. SY神犇说树套树注重的是内外层的数据结构的选择问题,果然很重要啊. 动态开点的实现方法很好. [代码] #include <cstdi ...
- BZOJ 3110: [Zjoi2013]K大数查询 [整体二分]
有N个位置,M个操作.操作有两种,每次操作如果是1 a b c的形式表示在第a个位置到第b个位置,每个位置加入一个数c如果是2 a b c形式,表示询问从第a个位置到第b个位置,第C大的数是多少. N ...
随机推荐
- js获取节点
demo1: <!-- <div id="test" v="1">你好</div> --> // console.log(t ...
- [转载]C#中播放背景音乐几种的方法
最经在写winform程序,其中有用到播放背景音乐 特此收集了一些网上的教程: 1.调用非托管的dll using System.Runtime.InteropServices; //DllImpor ...
- 转Spring+Hibernate+EHcache配置(三)
配置每一项的详细作用不再详细解释,有兴趣的请google下 ,这里需要注意一点defaultCache标签定义了一个默认的Cache,这个Cache是不能删除的,否则会抛出No default cac ...
- 论MOBA类游戏五号位的重要性
观众朋友们,也许你对题目很好奇,才打开这篇文章.为什么技术圈中会出现游戏类的软文?如果时间充足,可以继续往下看. MOBA 类游戏的兴起,逐渐吞噬游戏市场,以病毒式的扩张方式肆意改变着游戏玩家内心对游 ...
- VARCHAR2转换为CLOB碰到ORA-22858错误
近日工作中发现有一张表的字段类型建错了,本应是BLOB类型却被别人建成了VARCHAR2(200),修改时oracle却提示“ORA-22858 invalid alteration of datat ...
- PYTHON设计模式,创建型之工厂方法模式
我感觉和上一个差不多,可能不要动最要的地方吧... #!/usr/bin/evn python #coding:utf8 class Pizza(object): def prepare(self, ...
- Android EditText边框颜色的selector 使用focus标记当前填写的框
案例:当选中一个EditText时,将其边框变为蓝色,其他未被选中的EditText则为灰色. 主界面: <?xml version="1.0" encoding=" ...
- SQLite入门与分析(四)---Page Cache之事务处理(1)
写在前面:从本章开始,将对SQLite的每个模块进行讨论.讨论的顺序按照我阅读SQLite的顺序来进行,由于项目的需要,以及时间关系,不能给出一个完整的计划,但是我会先讨论我认为比较重要的内容.本节讨 ...
- Power Station POJ 4045
题意:给你一棵树,让你求一点,使该点到其余各点的距离之和最小.如果这样的点有多个,则按升序依次输出. 树型dp #include <cstdio> #include <cstring ...
- P114、面试题17:合并两个排序的链表
题目:输入两个递增排序的链表,合并这两个链表并使新链表中的结点仍然是按照递增顺序的.struct ListNode{ int m_nKey; ListNode* m_p ...