K大数查询
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
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操作中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大数查询的更多相关文章
- BZOJ 3110: [Zjoi2013]K大数查询 [树套树]
3110: [Zjoi2013]K大数查询 Time Limit: 20 Sec Memory Limit: 512 MBSubmit: 6050 Solved: 2007[Submit][Sta ...
- 区间K 大数查询
算法训练 区间k大数查询 时间限制:1.0s 内存限制:256.0MB 问题描述 给定一个序列,每次询问序列中第l个数到第r个数中第K大的数是哪个. 输入格式 第一行包含一个数n,表示序列 ...
- 蓝桥杯 算法训练 区间k大数查询(水题)
算法训练 区间k大数查询 时间限制:1.0s 内存限制:256.0MB 问题描述 给定一个序列,每次询问序列中第l个数到第r个数中第K大的数是哪个. 输入格式 第一行包含一个数n,表示序列长度. ...
- 算法训练 区间k大数查询
http://lx.lanqiao.org/problem.page?gpid=T11 算法训练 区间k大数查询 时间限制:1.0s 内存限制:256.0MB 问题描述 给定一个 ...
- 树套树专题——bzoj 3110: [Zjoi2013] K大数查询 & 3236 [Ahoi2013] 作业 题解
[原题1] 3110: [Zjoi2013]K大数查询 Time Limit: 20 Sec Memory Limit: 512 MB Submit: 978 Solved: 476 Descri ...
- 蓝桥杯--算法训练 区间k大数查询
算法训练 区间k大数查询 时间限制:1.0 ...
- 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][ ...
- C语言 · 区间K大数查询
问题描述 给定一个序列,每次询问序列中第l个数到第r个数中第K大的数是哪个. 输入格式 第一行包含一个数n,表示序列长度. 第二行包含n个正整数,表示给定的序列. 第三个包含一个正整数m,表示询问个数 ...
随机推荐
- case when in sql server's stored procedure
https://docs.microsoft.com/en-us/sql/t-sql/language-elements/case-transact-sql Evaluates a list of c ...
- CodeForces A. Meeting of Old Friends
2019-05-30 20:19:57 加油!!! sort(a + 1, a + 5); 卡了一会儿 #include <bits/stdc++.h> using namespace s ...
- Java NIO Buffer说明
Buffer 有3个重要的参数:位置(position).容量(capactiy).上限(limit) 位置(position): 写:当前缓冲区的位置,将从position的下一个位置写数据. 读: ...
- Selenium获取input值的两种方法:WebElement.getAttribute("value")和WebElement.getText()
在页面元素的定位中,有时候需要获取到元素的页面显示值,用来作为断言.例如,我需要获取email的值"amy1111@xxx.com". <input class=" ...
- ios 指纹识别解锁
:添加LocalAuthentication.framework框架 :实现过程 #import "ViewController.h" #import <LocalAuthe ...
- [hihocoder][Offer收割]编程练习赛59
替换函数 #pragma comment(linker, "/STACK:102400000,102400000") #include<stdio.h> #includ ...
- VmWare 安装 Centos
VMware CentOS7 的 ISO 文件 方法/步骤 1 打开虚拟机软件“VMware”,选择“创建新的虚拟机”: 2 选择“自定义(高级)”选项,点击“下一步”: 3 在“硬件兼容性”处选 ...
- Swift进阶之内存模型和方法调度
前言 Apple今年推出了Swift3.0,较2.3来说,3.0是一次重大的升级.关于这次更新,在这里都可以找到,最主要的还是提高了Swift的性能,优化了Swift API的设计(命名)规范. 前段 ...
- html 图片翻转
var Lb = false; var Ub = false; function rotate(obj) { if (obj == "L") { if (Lb == false) ...
- 将 GNOME 默认的界面切换动画功能关闭
gsettings set org.gnome.desktop.interface enable-animations false