POJ 2104 - 主席树 / 询问莫队+权值分块
题目大意应该都清楚。
今天看到一篇博客用分块+莫对做了这道题,直接惊呆了。
首先常规地离散化后将询问分块,对于某一询问,将莫队指针移动到指定区间,移动的同时处理权值分块的数字出现次数(单独、整块),莫队完后,现在的权值分块就是关于当前区间的。然后再从左到右扫描分块,直到数字个数+该块个数>=k,这时进入该块逐个加,当数字个数>=k时,直接跳出输出离散化之前的数字。
试了很多种块的大小,最后还是选择sqrt(100000) ≈ 320,时间比我的主席树还少(肯定是我写的丑)。
code
1040ms
#include<iostream>
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<cmath>
#include<string>
#include<algorithm>
using namespace std;
const int N = 1e5 + 5, M = 5e3 + 5, S = 320;
int n, m;
int val[N], b[N], len, cnt[S], num_cnt[N], ans[M];
struct QRY{
int x, y, k, mo_bl, id;
inline bool operator < (const QRY &b) const{
return mo_bl < b.mo_bl || (mo_bl == b.mo_bl && y < b.y);
}
}qry[M];
int head, tail;
namespace IO{
inline int read(){
int i = 0, f = 1; char ch = getchar();
for(; (ch < '0' || ch > '9') && ch != '-'; ch = getchar());
if(ch == '-') f = -1, ch = getchar();
for(; ch >= '0' && ch <= '9'; ch = getchar()) i = (i << 3) + (i << 1) + (ch - '0');
return i * f;
}
inline void wr(int x){
if(x < 0) putchar('-'), x = -x;
if(x > 9) wr(x / 10);
putchar(x % 10 + '0');
}
}using namespace IO;
inline void disc_init(){
sort(b + 1, b + len + 1);
len = unique(b + 1, b + len + 1) - b - 1;
for(int i = 1; i <= n; i++) val[i] = lower_bound(b + 1, b + len + 1, val[i]) - b;
}
inline void handleMo(int l, int r){
while(head < l){
int part_bl = val[head] / S + (val[head] % S ? 1 : 0);
cnt[part_bl]--;
num_cnt[val[head]]--;
head++;
}
while(head > l){
head--;
int part_bl = val[head] / S + (val[head] % S ? 1 : 0);
cnt[part_bl]++;
num_cnt[val[head]]++;
}
while(tail < r){
tail++;
int part_bl = val[tail] / S + (val[tail] % S ? 1 : 0);
cnt[part_bl]++;
num_cnt[val[tail]]++;
}
while(tail > r){
int part_bl = val[tail] / S + (val[tail] % S ? 1 : 0);
cnt[part_bl]--;
num_cnt[val[tail]]--;
tail--;
}
}
int main(){
freopen("h.in", "r", stdin);
n = read(), m = read();
for(int i = 1; i <= n; i++) val[i] = b[++len] = read();
disc_init();
for(int i = 1; i <= m; i++){
int x = read(), y = read(), k = read(), bl = x / S + (x % S ? 1 : 0);
qry[i] = (QRY){x, y, k, bl, i};
}
sort(qry + 1, qry + m + 1);
head = tail = 0;
for(int i = 1; i <= m; i++){
int l = qry[i].x, r = qry[i].y, k = qry[i].k, sum = 0;
handleMo(l, r);
int now = 1;
try{
while(sum + cnt[now] < k) sum += cnt[now++];
for(int j = (now - 1) * S + 1; j <= min(n, now * S); j++)
if(sum + num_cnt[j] < k) sum += num_cnt[j];
else throw(j);
}
catch(int x){
ans[qry[i].id] = b[x];
continue;
}
}
for(int i = 1; i <= m; i++) wr(ans[i]), putchar('\n');
return 0;
}
POJ 2104 - 主席树 / 询问莫队+权值分块的更多相关文章
- 2019.01.08 bzoj3809: Gty的二逼妹子序列(莫队+权值分块)
传送门 题意:多组询问,问区间[l,r]中权值在[a,b]间的数的种类数. 看了一眼大家应该都知道要莫队了吧. 然后很容易想到用树状数组优化修改和查询做到O(mnlogamax)O(m\sqrt nl ...
- BZOJ 3339 && BZOJ 3585 莫队+权值分块
显然若一个数大于n就不可能是答案. #include <iostream> #include <cstring> #include <cstdio> #includ ...
- K-th Number Poj - 2104 主席树
K-th Number Poj - 2104 主席树 题意 给你n数字,然后有m次询问,询问一段区间内的第k小的数. 解题思路 这个题是限时训练做的题,我不会,看到这个题我开始是拒绝的,虽然题意清晰简 ...
- [poj 2104]主席树+静态区间第k大
题目链接:http://poj.org/problem?id=2104 主席树入门题目,主席树其实就是可持久化权值线段树,rt[i]维护了前i个数中第i大(小)的数出现次数的信息,通过查询两棵树的差即 ...
- BZOJ 1878 [SDOI2009]HH的项链 (主席树 或 莫队算法)
题目链接 HH的项链 这道题可以直接上主席树的模板 #include <bits/stdc++.h> using namespace std; #define rep(i, a, b) ...
- poj 2104 主席树(区间第k大)
K-th Number Time Limit: 20000MS Memory Limit: 65536K Total Submissions: 44940 Accepted: 14946 Ca ...
- POJ 2104 主席树模板题
#include <iostream> #include <cstdio> #include <algorithm> int const maxn = 200010 ...
- 【莫队算法】【权值分块】bzoj2223 [Coci 2009]PATULJCI
不带修改主席树裸题<=>莫队+权值分块裸题. 复杂度O(m*sqrt(n)). P.S.题目描述坑爹,第二个数是权值的范围. #include<cstdio> #include ...
- 【带修莫队】【权值分块】bzoj3196 Tyvj 1730 二逼平衡树
这题用了三种算法写: 分块+二分:O(n*sqrt(n*log(n)) 函数式权值分块:O(n*sqrt(n)) 带修莫队+权值分块:O(n5/3) 结果……复杂度越高的实际上跑得越快……最后这个竟然 ...
随机推荐
- Vue使用Promise自定义confirm确认框组件
使用Promise模拟浏览器确认框,可自定义标题,内容,按钮文字和类型 参数名 类型 说明 title String 标题 content String 内容 yesBtnText String 确认 ...
- volatile关键字深入理解
前言: 这个关键字的重点就三个字,就是可见性.但是面试的时候,你说出可见性三个字,基本上满分100的话,最多只能得到20分.剩下的那80分,就要靠你用硬功夫去获得了. 所谓的硬功夫,其实就是要整明白, ...
- 关于Altium Designer重新修改某一原件pcb封装的问题
在重新导入的时候可能会影响到类class,所以可能是原理图中没有类吧 上图中的comment的修改是表示下面图片中的 comment栏的改变:
- hcharts实现堆叠柱形图
<!DOCTYPE > <html> <head> <meta charset="utf-8"><link rel=" ...
- 三国武将查询系统 //Java 訪问 数据库
import java.awt.*; import javax.swing.*; import java.awt.event.ActionListener; import java.awt.event ...
- POJ 2590 Steps (ZOJ 1871)
http://poj.org/problem?id=2590 http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemCode=1871 题目大 ...
- jquery常用方法总结(转)
取值与赋值操作 $("#ID").val(); //取value值 $("#ID").val("xxx"); //赋值 $("#I ...
- icvPrecalculate
/* *icvPrecalculate *作用:计算特征值,并排序 *详细来说也就是依据训练样本信息和haar特征信息,在函数内部引用icvGetTrainingDataCallback来 *分批计算 ...
- 目前以lib后缀的库有两种,一种为静态链接库(Static Libary,以下简称“静态库”),另一种为动态连接库(DLL,以下简称“动态库”)的导入库(Import Libary,以下简称“导入库”)。静态库是一个或者多个obj文件的打包
前以lib后缀的库有两种,一种为静态链接库(Static Libary,以下简称“静态库”),另一种为动态连接库(DLL,以下简称“动态库”)的导入库(Import Libary,以下简称“导入库”) ...
- layer iframe 之间传值和关闭iframe弹窗
1.访问父页面元素值 var parentId=parent.$("#id").val();//访问父页面元素值 2.访问父页面方法 var parentMethodValue=p ...