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. 通过指针访问C++对象的私有成员

    C++对象的私有成员是禁止类外的访问的.但是我们仍然可以通过指针访问C++对象的私有成员. #include <iostream> using namespace std; class A ...

  2. 生活的 tricks

    1. 远距离传递 传真(需要附近有传真机):发 QQ.微信拍照,自己打印: 2. 超市的设计 如果是两层的话,入口一定在第一楼,出口在第二楼,也即当你需要出去的时候,需要贯穿整个超市: 用的在第一楼: ...

  3. 杂项-Java:EL表达式

    ylbtech-杂项-Java:EL表达式 EL(Expression Language) 是为了使JSP写起来更加简单.表达式语言的灵感来自于 ECMAScript 和 XPath 表达式语言,它提 ...

  4. Java插入中文到数据库中文变成问号解决

    转自:https://blog.csdn.net/hellosweet1/article/details/81673152 之所以会出现乱码,就是编码方式不一致导致的 我们应该首先确定         ...

  5. diaowen Maven Webapp

    五月 , :: 上午 org.apache.catalina.startup.VersionLoggerListener log INFO: Server version: Apache Tomcat ...

  6. BZOJ 4562 搜索...

    思路: 统计入度&出度 每搜到一个点 in[v[i]]--,f[v[i]]+=f[t]; if(!in[v[i]])if(out[v[i]])q.push(v[i]);else ans+=f[ ...

  7. ASP.NET的Eval方法和Bind方法的区别

    Eval是只读的方法(单向数据在邦定),所邦定的内容为不会提交回服务器. 比如图书的ISBN,并不想让用户做任何修改,可以使用<%# Eval('ISBN').TOString().Trim() ...

  8. js基础---字符串方法

    // var str1="xudandan"; // 字符串长度 var str1_length=str1.length;console.log(str1);console.log ...

  9. JavaScript变量提升及作用域

    今天在知乎看前端面试题的时候,看到这样的问题,发现自己懂的真的是太少了,看了给的例子,所以写一下自己的理解. 首先放一段代码: var v= “hello JavaScript”; alert(v); ...

  10. PL/SQL之高级篇

    原文地址:http://www.cnblogs.com/sin90lzc/archive/2012/08/30/2661117.html 参考文献:<Oracle完全学习手册> 1.概述 ...