传送门

题目大意应该都清楚。

今天看到一篇博客用分块+莫对做了这道题,直接惊呆了。

首先常规地离散化后将询问分块,对于某一询问,将莫队指针移动到指定区间,移动的同时处理权值分块的数字出现次数(单独、整块),莫队完后,现在的权值分块就是关于当前区间的。然后再从左到右扫描分块,直到数字个数+该块个数>=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 - 主席树 / 询问莫队+权值分块的更多相关文章

  1. 2019.01.08 bzoj3809: Gty的二逼妹子序列(莫队+权值分块)

    传送门 题意:多组询问,问区间[l,r]中权值在[a,b]间的数的种类数. 看了一眼大家应该都知道要莫队了吧. 然后很容易想到用树状数组优化修改和查询做到O(mnlogamax)O(m\sqrt nl ...

  2. BZOJ 3339 && BZOJ 3585 莫队+权值分块

    显然若一个数大于n就不可能是答案. #include <iostream> #include <cstring> #include <cstdio> #includ ...

  3. K-th Number Poj - 2104 主席树

    K-th Number Poj - 2104 主席树 题意 给你n数字,然后有m次询问,询问一段区间内的第k小的数. 解题思路 这个题是限时训练做的题,我不会,看到这个题我开始是拒绝的,虽然题意清晰简 ...

  4. [poj 2104]主席树+静态区间第k大

    题目链接:http://poj.org/problem?id=2104 主席树入门题目,主席树其实就是可持久化权值线段树,rt[i]维护了前i个数中第i大(小)的数出现次数的信息,通过查询两棵树的差即 ...

  5. BZOJ 1878 [SDOI2009]HH的项链 (主席树 或 莫队算法)

    题目链接  HH的项链 这道题可以直接上主席树的模板 #include <bits/stdc++.h> using namespace std; #define rep(i, a, b) ...

  6. poj 2104 主席树(区间第k大)

    K-th Number Time Limit: 20000MS   Memory Limit: 65536K Total Submissions: 44940   Accepted: 14946 Ca ...

  7. POJ 2104 主席树模板题

    #include <iostream> #include <cstdio> #include <algorithm> int const maxn = 200010 ...

  8. 【莫队算法】【权值分块】bzoj2223 [Coci 2009]PATULJCI

    不带修改主席树裸题<=>莫队+权值分块裸题. 复杂度O(m*sqrt(n)). P.S.题目描述坑爹,第二个数是权值的范围. #include<cstdio> #include ...

  9. 【带修莫队】【权值分块】bzoj3196 Tyvj 1730 二逼平衡树

    这题用了三种算法写: 分块+二分:O(n*sqrt(n*log(n)) 函数式权值分块:O(n*sqrt(n)) 带修莫队+权值分块:O(n5/3) 结果……复杂度越高的实际上跑得越快……最后这个竟然 ...

随机推荐

  1. Python的数组合并

    https://blog.csdn.net/hustqb/article/details/78090365 TypeError: can only concatenate list (not &quo ...

  2. DataTable +chart控件

    //这是仿你的DataTable //-----开始--------- DataTable dataTable1 = new System.Data.DataTable(); dataTable1.C ...

  3. Java Web学习总结(14)——JSP基础语法

    任何语言都有自己的语法,JAVA中有,JSP虽然是在JAVA上的一种应用,但是依然有其自己扩充的语法,而且在JSP中,所有的JAVA语句都可以使用. 一.JSP模版元素 JSP页面中的HTML内容称之 ...

  4. AIX上安装Oracle10G软件

    安装准备 (1)确认系统版本号.内核版本号 # oslevel –r   //查看操作系统版本号 //-08能够安装10g,-09能够安装11g watermark/2/text/aHR0cDovL2 ...

  5. 好记性不如烂笔头——double

    两个数据转换成double型做差,会出现误差,转换成Decimal就OK了.

  6. 8、for 、emumrate、range、if

    1.for循环用户按照顺序循环可迭代对象中的内容,PS:break.continueli = [11,22,33,44]for item in li: print item 2.enumrate 为可 ...

  7. 【Codeforces Round #443 (Div. 2) A】Borya's Diagnosis

    [链接] 我是链接,点我呀:) [题意] 在这里输入题意 [题解] 模拟 [代码] #include <bits/stdc++.h> using namespace std; const ...

  8. TF卡电压 SD卡引脚

    //////////////////////////////////////////////////////////////////////////////////////////////////// ...

  9. 7.1 基础知识Android消息处理机制

    1. Android消息处理机制: Handler, MessageQueue, Looper, Thread 线程概念 : 一个应用程序运行时它的主体被称为进程, 一个进程内部可以有多个线程, 线程 ...

  10. [RxJS] RefCount: automatically starting and stopping an execution

    With the connect() method on a ConnectableObservable, the programmer is responsible for avoiding lea ...