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,表示询问个数 ...
随机推荐
- HDU3183 RMQ/贪心
A Magic Lamp Problem Description Kiki likes traveling. One day she finds a magic lamp, unfortunately ...
- luogu1169 棋盘制作
题目大意 有一个有m*n个格子的矩形,每个格子都有黑或白两种颜色.现要求将该矩形分别裁剪成一个小矩形或一个小正方形,使得这个矩形和正方形是个国际象棋棋盘,且面积最大. 题解 首先,为了简化问题,我们每 ...
- ambarella H2 添加文件到ext4文件系统
方法1: ambarella/rootfs目录下有skeleton(骨架)目录,此目录下就是文件系统的各个目录, [root@jz4775dev]# ls skeleton/ bin debug de ...
- ListView实现简单列表
ListView实现简单列表 效果图: 啥也没干的ListView张这样: fry.Activity01 package fry; import com.example.ListView.R; imp ...
- 把一个文件夹下的多个csv文件合并到一个excel的多个sheet
#!/usr/bin/env python3 # -*- coding: UTF-8 -*- import pandas as pd import os import re if __name__ = ...
- 希尔shell排序——java实现
希尔排序是对插入排序的优化,将插入排序的交换步长由1增加到h. 希尔排序的思想是使数组中任意间隔为h的元素有序.步长调幅为h = 3*h + 1, 也就是1,4,13,40,121,364, 1003 ...
- POJ 1946 DP
折腾了一晚上 明天再写.. 2016.5.17 23:59 -> -> #include <cstdio> #include <cstring> #include ...
- SQLServer2008 字符串函数一览表
/* 字符串函数 (PS.索引都从1开始计算)*/ /* 指定字符(或字符串)A.字符串B.起始索引.获得A在B中的索引值.*/select Charindex('d','abcdefg',0) -- ...
- objc_setAssociatedObject获取cell上button对应所在的行
#import <UIKit/UIKit.h> @interface TestCell : UITableViewCell @property (weak, nonatomic) IBOu ...
- 解决emlog默认导航不能修改的问题以及修改后台登录地址的方法
修改默认导航 我们需要使用修改代码的方式来解决 首先找到admin/navbar.php文件 然后找到需要删除的几行代码: if ($type != Navi_Model::navitype_cust ...