3110: [Zjoi2013]K大数查询

Time Limit: 20 Sec  Memory Limit: 512 MB

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操作中c<=Maxlongint

分析:区间线段树套权值线段树;

    修改时就把对应权值范围内的线段树区间修改;

    查询时二分查询即可;

    看博客发现lazy不pushdown直接永久化标记会更快,orz;

代码:

#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <cmath>
#include <algorithm>
#include <climits>
#include <cstring>
#include <string>
#include <set>
#include <bitset>
#include <map>
#include <queue>
#include <stack>
#include <vector>
#define rep(i,m,n) for(i=m;i<=n;i++)
#define mod 1000000007
#define inf 0x3f3f3f3f
#define vi vector<int>
#define pb push_back
#define mp make_pair
#define fi first
#define se second
#define ll long long
#define pi acos(-1.0)
#define pii pair<int,int>
#define sys system("pause")
const int maxn=5e4+;
const int M=maxn**;
using namespace std;
inline ll gcd(ll p,ll q){return q==?p:gcd(q,p%q);}
inline ll qpow(ll p,ll q){ll f=;while(q){if(q&)f=f*p;p=p*p;q>>=;}return f;}
inline int id(int l,int r){return l+r|l!=r;}
inline void umax(ll &p,ll q){if(p<q)p=q;}
inline void umin(ll &p,ll q){if(p>q)p=q;}
inline ll read()
{
ll x=;int f=;char ch=getchar();
while(ch<''||ch>''){if(ch=='-')f=-;ch=getchar();}
while(ch>=''&&ch<=''){x=x*+ch-'';ch=getchar();}
return x*f;
}
int n,m,k,t,root[maxn*],ls[M],rs[M],sz,num,L,R;
ll sum[M],lazy[M],a[maxn];
struct node
{
int a,b,c;
ll d;
}q[maxn];
void push_down(int l,int r,int k)
{
int mid=l+r>>;
if(!ls[k])ls[k]=++sz;
if(!rs[k])rs[k]=++sz;
sum[ls[k]]+=lazy[k]*(mid-l+);
sum[rs[k]]+=lazy[k]*(r-mid);
lazy[ls[k]]+=lazy[k],lazy[rs[k]]+=lazy[k];
lazy[k]=;
}
void push_up(int k){sum[k]=sum[ls[k]]+sum[rs[k]];}
void insert(int L,int R,int l,int r,int&k)
{
if(!k)k=++sz;
if(l==L&&r==R)
{
lazy[k]++;
sum[k]+=r-l+;
return;
}
int mid=l+r>>;
if(lazy[k])push_down(l,r,k);
if(R<=mid)insert(L,R,l,mid,ls[k]);
else if(L>mid)insert(L,R,mid+,r,rs[k]);
else
{
insert(L,mid,l,mid,ls[k]);
insert(mid+,R,mid+,r,rs[k]);
}
push_up(k);
}
ll cal(int L,int R,int l,int r,int k)
{
if(l==L&&r==R)return sum[k];
int mid=l+r>>;
if(lazy[k])push_down(l,r,k);
if(R<=mid)return cal(L,R,l,mid,ls[k]);
else if(L>mid)return cal(L,R,mid+,r,rs[k]);
else return cal(L,mid,l,mid,ls[k])+cal(mid+,R,mid+,r,rs[k]);
}
void add(int L,int R,int l,int r,int x)
{
insert(L,R,,n,root[id(l,r)]);
if(l==r)return;
int mid=l+r>>;
if(x<=mid)add(L,R,l,mid,x);
else add(L,R,mid+,r,x);
}
int gao(int L,int R,int l,int r,ll x)
{
if(l==r)return l;
int mid=l+r>>;
ll tmp;
tmp=cal(L,R,,n,root[id(mid+,r)]);
if(tmp>=x)return gao(L,R,mid+,r,x);
else return gao(L,R,l,mid,x-tmp);
}
int main()
{
int i,j;
scanf("%d%d",&n,&m);
rep(i,,m)
{
scanf("%d%d%d%lld",&q[i].a,&q[i].b,&q[i].c,&q[i].d);
if(q[i].a==)a[++num]=q[i].d;
}
sort(a+,a+num+);
num=unique(a+,a+num+)-a-;
rep(i,,m)
{
if(q[i].a==)
{
q[i].d=lower_bound(a+,a+num+,q[i].d)-a;
add(q[i].b,q[i].c,,num,q[i].d);
}
else
{
printf("%lld\n",a[gao(q[i].b,q[i].c,,num,q[i].d)]);
}
}
return ;
}

K大数查询的更多相关文章

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

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

  2. 区间K 大数查询

      算法训练 区间k大数查询   时间限制:1.0s   内存限制:256.0MB 问题描述 给定一个序列,每次询问序列中第l个数到第r个数中第K大的数是哪个. 输入格式 第一行包含一个数n,表示序列 ...

  3. 蓝桥杯 算法训练 区间k大数查询(水题)

    算法训练 区间k大数查询 时间限制:1.0s   内存限制:256.0MB 问题描述 给定一个序列,每次询问序列中第l个数到第r个数中第K大的数是哪个. 输入格式 第一行包含一个数n,表示序列长度. ...

  4. 算法训练 区间k大数查询

    http://lx.lanqiao.org/problem.page?gpid=T11 算法训练 区间k大数查询   时间限制:1.0s   内存限制:256.0MB        问题描述 给定一个 ...

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

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

  6. 蓝桥杯--算法训练 区间k大数查询

                                                                                 算法训练 区间k大数查询   时间限制:1.0 ...

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

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

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

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

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

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

  10. C语言 · 区间K大数查询

    问题描述 给定一个序列,每次询问序列中第l个数到第r个数中第K大的数是哪个. 输入格式 第一行包含一个数n,表示序列长度. 第二行包含n个正整数,表示给定的序列. 第三个包含一个正整数m,表示询问个数 ...

随机推荐

  1. Homebrew 命令

    安装(需要 Ruby):ruby -e "$(curl -fsSL https://raw.github.com/Homebrew/homebrew/go/install)" 搜索 ...

  2. XML案例(简单的考生成绩管理系统)

    1.以如下格式的exam.xml文件为例 <?xml version="1.0" encoding="UTF-8" standalone="no ...

  3. Django day15 (二) csrf的 跨站请求伪造 与 局部禁用 , 局部使用

    一:  csrf 的跨站请求伪造 二: csrf 的局部禁用 , 局部使用

  4. Django day03 orm介绍

    一:orm介绍 就是对象关系映射,python当中的类能够对应到数据库当中的某一个表(一个类对应一个表),一个类的对象对应着数据库中的一条记录,类当中的某个字段对应着数据库当中表的字段,字段拥有不同的 ...

  5. JavaScript是按值传递还是按引用传递?

    JavaScript是按值传递的,但是要分情况才知道传递之后原来的值会不会变,不然会出现你想都想不出来的bug 一.按值传递--元类型输入tip:元类型( number, string, boolea ...

  6. 【寒假集训系列DAY3】

    DAY2的坑之后会补上 DAY3 今天暴力分拿的还是不错的...60+30+25=115,但还是太弱了呀,每题都只会暴力(话说第3题直接输-1给了15分,本以为只会给5分,然后打了半个小时的爆搜... ...

  7. SQL之LEFT JOIN,EIGHT JOIN,INSERT JOIN的区别

    left join(左联接) 返回包括左表中的所有记录和右表中联结字段相等的记录 right join(右联接) 返回包括右表中的所有记录和左表中联结字段相等的记录inner join(等值连接) 只 ...

  8. itext 生成pdf文档 小结(自己备忘)

    1.引入maven <dependency> <groupId>com.itextpdf</groupId> <artifactId>itextpdf& ...

  9. 在mac上截屏的几种方式

    方法 1: 对屏幕的一部分进行截图 按下Command+Shift+4   方法 2: 对整个屏幕进行截图 按下Command+Shift+3   方法 3: 把截图保存到粘贴板 按下Command+ ...

  10. view在使用shape属性加圆角的同时,用代码修改其他background属性(例如颜色)不生效

    项目中一个TextView控件设置了shape属性,给其加了圆角,如下: houlder.mtxtGovernmentType.setBackgroundResource(R.drawable.tv_ ...