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

思路:

都是从浙江挂下来的考数据结构的歪风邪气←_←
一看就知道是数据结构题啦=。=
树套树。。我是写的树状数组套线段树。
外层的树状数组记录有关数字的信息,内层的线段树记录有关位置的信息。
也就是说我在[5,8]中加入了3这个数,就在外层的树状数组add_bit(3),然后在树状数组对应的节点上把[5,8]这个节点打上+1的标记。
每次对于一个询问[L,R]中第k大的数,我们先转化为求第k小,然后二分答案,寻找在[l,r]中有多少比Mid小的数,收缩上下界就行了。
p.s 网上说开树套树空间会爆,所以内层线段树要动态开点,我不知道要不要。。反正我是动态的。。不过跟静态的应该区别还是挺大的。
 #include <iostream>
#include <cstring>
#include <string>
#include <cstdio>
#include <cstdlib>
#include <cmath>
#include <algorithm>
#include <queue>
#include <stack>
#include <map>
#include <set>
#include <list>
#include <vector>
#include <ctime>
#include <functional>
#define pritnf printf
#define scafn scanf
#define For(i,j,k) for(int i=(j);i<=(k);(i)++)
#define Clear(a) memset(a,0,sizeof(a))
using namespace std;
typedef long long LL;
typedef unsigned int Uint;
const int INF=0x3fffffff;
//==============struct declaration==============
struct Node{
Node *lc,*rc;
long long sum,add;
Node(){lc=rc=NULL;sum=add=;}
};
//==============var declaration=================
const int MAXN=;
int n,m,L,R;
long long sum[MAXN*],addv[MAXN*];
Node *BitTree[MAXN];
//==============function declaration============
int lowbit(int x){return x&-x;}
void add_bit(int x);
void add_seg(Node *&o,int l,int r);
long long query_bit(int x);
long long query_seg(Node *&i,int l,int r,long long add);
void update(Node *&o,int l,int r);
void add_num(int o,int l,int r);
long long query_num(int o,int l,int r,long long add);
//==============main code=======================
int main()
{
#define FILE__
#ifdef FILE__
freopen("input","r",stdin);
freopen("output","w",stdout);
#endif
scanf("%d%d",&n,&m);n++;
for(int i=;i<=n;i++) BitTree[i]=NULL;
while (m--){
int cmd,a,b;long long c;scanf("%d%d%d%lld",&cmd,&a,&b,&c);
if (cmd==){
L=a;R=b;
add_bit(c);add_num(,,n-);
}
else if (cmd==){
int low=,high=n-,mid;
L=a;R=b;
long long Num_Exist=query_num(,,n-,);
c=Num_Exist-c+;
while (low<high){
mid=(low+high)>>;
long long tmp=query_bit(mid);
if (tmp<c) low=mid+;
if (tmp>=c) high=mid;
}
printf("%d\n",low);
}
}
return ;
}
//================fuction code====================
void add_bit(int x){
while (x<=n){
add_seg(BitTree[x],,n-);
x+=lowbit(x);
}
}
void add_seg(Node *&o,int l,int r){
int m=(l+r)>>;
if (o==NULL) o=new(Node);
if (L<=l&&r<=R){
o->add++;
update(o,l,r);
return;
}
if (m>=L) add_seg(o->lc,l,m);
if (m<R) add_seg(o->rc,m+,r);
update(o,l,r);
}
void update(Node *&o,int l,int r){
o->sum=;
if (o->lc!=NULL) o->sum+=o->lc->sum;
if (o->rc!=NULL) o->sum+=o->rc->sum;
o->sum+=(r-l+)*o->add;
}
long long query_bit(int x){
long long res=;
while (x>){
res+=query_seg(BitTree[x],,n-,);
x-=lowbit(x);
}
return res;
}
long long query_seg(Node *&o,int l,int r,long long add){
if (o==NULL) return add*(min(r,R)-max(l,L)+);
int m=(l+r)>>;
if (L<=l&&r<=R)
return o->sum+(r-l+)*add;
long long Left=,Right=;
if (m>=L) Left=query_seg(o->lc,l,m,add+o->add);
if (m<R) Right=query_seg(o->rc,m+,r,add+o->add);
return Left+Right;
}
void add_num(int o,int l,int r){
if (L<=l&&r<=R){
addv[o]++;
sum[o]+=r-l+;
}
else{
int lc=o*,rc=o*+,m=(l+r)>>;
if (m>=L) add_num(lc,l,m);
if (m<R) add_num(rc,m+,r);
sum[o]=sum[lc]+sum[rc]+addv[o]*(r-l+);
}
}
long long query_num(int o,int l,int r,long long add){
int lc=o*,rc=o*+,m=(l+r)>>;
if (L<=l&&r<=R)
return sum[o]+add*(r-l+);
long long Left=,Right=;
if (m>=L) Left=query_num(lc,l,m,add+addv[o]);
if (m<R) Right=query_num(rc,m+,r,add+addv[o]);
return Left+Right;
}

Prob_3110




【ZJOI2013】k大数查询 BZOJ 3110的更多相关文章

  1. K大数查询 BZOJ 3110

    K大数查询 [问题描述] 有N个位置,M个操作.操作有两种,每次操作如果是1 a b c的形式表示在第a个位置到第b个位置,每个位置加入一个数c如果是2 a b c形式,表示询问从第a个位置到第b个位 ...

  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. 3110: [Zjoi2013]K大数查询

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

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

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

随机推荐

  1. 匈牙利算法与KM算法

    匈牙利算法 var i,j,k,l,n,m,v,mm,ans:longint; a:..,..]of longint; p,f:..]of longint; function xyl(x,y:long ...

  2. Spring系列:学习Spring的资源和讨论

    1) 阅读<spring in action 4th edition>,这样可以对的spring可以做什么事情有个基本了解: 2) 阅读spring.io官网提供的各种reference, ...

  3. C#进阶系列——DDD领域驱动设计初探(四):WCF搭建

    前言:前面三篇分享了下DDD里面的两个主要特性:聚合和仓储.领域层的搭建基本完成,当然还涉及到领域事件和领域服务的部分,后面再项目搭建的过程中慢慢引入,博主的思路是先将整个架构走通,然后一步一步来添加 ...

  4. Asp.Net MVC3 简单入门详解过滤器Filter(转)

    前言 在开发大项目的时候总会有相关的AOP面向切面编程的组件,而MVC(特指:Asp.Net MVC,以下皆同)项目中不想让MVC开发人员去关心和写类似身份验证,日志,异常,行为截取等这部分重复的代码 ...

  5. ES6新特性:使用新方法定义javascript的Class

    ES6中定义类的方式, 就是ES3和ES5中定义类的语法糖,虽然也有些区别,但是整体定义类的方式更加简洁,类的继承更加方便, 如果想对ES6中的继承更加熟悉, 最好了解ES5中原型继承的方式, 博客园 ...

  6. jsonp 跨域请求

    背景: JavaScript是一种在Web开发中经常使用的前端动态脚本技术.在JavaScript中,有一个很重要的安全性限制,被称为"Same-Origin Policy"(同源 ...

  7. Ubuntu/mint清理系统垃圾

    Ubuntu Linux与Windows系统不同,Ubuntu Linux不会产生无用垃圾文件,但是在升级缓存中,Ubuntu Linux不会自动删除这些文件,今天就来说说这些垃圾文件清理方法.  1 ...

  8. jsp通过session传递checkbox中的值

    获取checkbox中的值(第一个页面) <% String foodName[]=request.getParameterValues("chioce"); //“chio ...

  9. COGS729. [网络流24题] 圆桌聚餐

    «问题描述:假设有来自m 个不同单位的代表参加一次国际会议.每个单位的代表数分别为ri(i=1,2,3...m), .会议餐厅共有n张餐桌,每张餐桌可容纳c i(i=1,2...n) 个代表就餐.为了 ...

  10. [bigdata] Spark RDD整理

    1. RDD是什么RDD:Spark的核心概念是RDD (resilient distributed dataset),指的是一个只读的,可分区的弹性分布式数据集,这个数据集的全部或部分可以缓存在内存 ...