传送门

题目大意应该都清楚。

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

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

    $(dom).offset() 方法返回或设置匹配元素相对于文档的偏移(位置).{left:100,top:100} $(dom).scrollTop() 方法返回或设置匹配元素的滚动条的垂直位置. ...

  2. 洛谷——P1046 陶陶摘苹果

    https://www.luogu.org/problem/show?pid=1046 题目描述 陶陶家的院子里有一棵苹果树,每到秋天树上就会结出10个苹果.苹果成熟的时候,陶陶就会跑去摘苹果.陶陶有 ...

  3. 2 Java基础语法(keyword,标识符,凝视,常量,进制转换,变量,数据类型,数据类型转换)

    1:keyword(掌握) (1)被Java语言赋予特定含义的单词 (2)特点: 所有小写. (3)注意事项: A:goto和const作为保留字存在. B:类似于Notepad++这种高级记事本会对 ...

  4. [Spark源代码剖析] DAGScheduler划分stage

    转载请标明出处:http://blog.csdn.net/bigbigdata/article/details/47293263 本文基于Spark 1.3.1 先上一些stage相关的知识点: DA ...

  5. 一个开源.net混淆器——ConfuserEx (收藏)

    一个开源.net混淆器——ConfuserEx http://yck1509.github.io/ConfuserEx/ 由于项目中要用到.net 混淆器,网上搜寻了很多款,比如Dotfuscator ...

  6. 网站图标——favicon

    首先推荐一个网站图标在线制作工具favicon: 插入图标只需在head中间加入以下代码: <link rel="icon" href="img/favicon.i ...

  7. XAMPP简介

    XAMPP是一款开源.免费的网络服务器软件,经过简单安装后,就可以在个人电脑上搭建服务器环境.本文为大家介绍Windows中安装XAMPP(Apache+Mysql+PHP)及使用方法及其相关问题的总 ...

  8. Web--CSS控制页面(link与import方式差别)

        先了解: [1]         "Table"和"DIV"这两个网页元素诞生的目的不同,首先Table诞生的目的是为了存储数据,而DIV诞生的目的就是 ...

  9. HDU 1556 Color the ball【算法的优化】

    /* 解题思路:每次仅仅求解一開始的第一个数字,让第一个数字加一,最后的一个数字的后面一个数减一.我们能够想想,最后加的时候,就是加上前面一个数出现的次数和自己本身出现的次数. 解题人:lingnic ...

  10. js的继承操作案例

    js的继承操作案例 一.总结 1.要案例要求,内心中想出操作要点 二.js的继承操作案例 案例 练习1:具有默认值的构造函数 实例描述: 有时候在创建对象时候,我们希望某些属性具有默认值 案例思路: ...