K-th Number POJ - 2104 (整体二分)

K-th Number

POJ - 2104

之前学主席树写了一遍

最近再看CDQ分治和整体二分,一直不是很理解,看着别人代码稍微理解了一些

 1 //比主席树慢了挺多
 2 #include <iostream>
 3 #include <cstring>
 4 #include <cstdio>
 5
 6 using namespace std;
 7
 8 const int maxn = 1e5 + 10;
 9 const int maxq = 5010;
10 const int inf = 0x3f3f3f3f;
11
12 struct Qry{
13     int x, y, k;
14     int id, type;
15     Qry(int x = 0, int y = 0, int k = 0, int id = 0, int type = 0):
16         x(x), y(y), k(k), id(id), type(type){}
17 }q[maxn + maxq], q1[maxn + maxq], q2[maxn + maxq];
18
19 struct Bit{
20     int n;
21     int a[maxn];
22     void init(int _n){
23         n = _n;
24         memset(a, 0, sizeof a);
25     }
26     void add(int i, int x){
27         for(; i <= n; i += i & -i) a[i] += x;
28     }
29     int sum(int i){
30         int res = 0;
31         for(; i; i -= i & -i) res += a[i];
32         return res;
33     }
34 }bit;
35
36 int n, m, a[maxn];
37 int ans[maxq];
38
39 void solve(int L, int R, int l, int r){
40     if(L > R) return;
41     if(l == r){
42         for(int i = L; i <= R; i++){
43             if(q[i].type == 2) ans[q[i].id] = l;
44         }
45         return;
46     }
47     int m = l + r >> 1;
48     int f = 0, g = 0;
49     for(int i = L; i <= R; i++){
50         if(q[i].type == 1){
51             if(q[i].x <= m) {
52                 bit.add(q[i].id, 1);
53                 q1[f++] = q[i];
54             }else q2[g++] = q[i];
55         }else{
56             int temp = bit.sum(q[i].y) - bit.sum(q[i].x - 1);
57             if(temp >= q[i].k) {
58                 q1[f++] = q[i];
59             }else{
60                 q[i].k -= temp;
61                 q2[g++] = q[i];
62             }
63         }
64     }
65     for(int i = 0; i < f; i++) if(q1[i].type == 1) bit.add(q1[i].id, -1);
66     memcpy(q + L, q1, f * sizeof(Qry));
67     memcpy(q + L + f, q2, g * sizeof(Qry));
68     solve(L, L + f - 1, l, m);
69     solve(L + f, R, m + 1, r);
70 }
71 int main(){
72     ios::sync_with_stdio(0);
73     while(cin>>n>>m){
74         bit.init(n);
75         int idx = 0;
76         for(int i = 1; i <= n; i++){
77             cin>>a[i];
78             q[++idx] = Qry(a[i], 0, 0, i, 1);
79         }
80         for(int i = 1; i <= m; i++){
81             int x, y, k;
82             cin>>x>>y>>k;
83             q[++idx] = Qry(x, y, k, i, 2);
84         }
85         solve(1, idx, -inf, inf);
86         for(int i = 1; i <= m; i++){
87             cout<<ans[i]<<endl;
88         }
89     }
90 }

原文地址:https://www.cnblogs.com/yijiull/p/8323703.html

时间: 2024-07-31 20:01:02

K-th Number POJ - 2104 (整体二分)的相关文章

K-th Number POJ - 2104 划分树

K-th Number You are working for Macrohard company in data structures department. After failing your previous task about key insertion you were asked to write a new data structure that would be able to return quickly k-th order statistics in the array

E - K-th Number POJ - 2104

You are working for Macrohard company in data structures department. After failing your previous task about key insertion you were asked to write a new data structure that would be able to return quickly k-th order statistics in the array segment. Th

hdu 2665 Kth number (poj 2104 K-th Number) 划分树

划分树的基本功能是,对一个给定的数组,求区间[l,r]内的第k大(小)数. 划分树的基本思想是分治,每次查询复杂度为O(log(n)),n是数组规模. 具体原理见http://baike.baidu.com/link?url=vIUKtsKYx7byeS2KCOHUI14bt_0sdHAa9BA1VceHdGsTv5jVq36SfZgBKdaHYUGqIGvIGrE_aJtqy0D0b1fCoq 个人感觉看代码是最好的学习方法. #include <cstdio> #include <c

整体二分专题

整体二分专题 A - K-th Number [POJ - 2104 ] \(1 <= n <= 100 000, 1 <= m <= 5 000\), 给出数组\(a[1..n](\leq1e9)\) 然后有\(m\)个询问, 每次询问\(Q(l,r,k)\)求\(a[l..r]\)之间从小到大第\(k\)个的数 B - Dynamic Rankings [ZOJ-2112] \(1 <= N <= 50,000 ~~~~ 1 <= M <= 10,000

POJ 2104:K-th Number(整体二分)

http://poj.org/problem?id=2104 题意:给出n个数和m个询问求区间第K小. 思路:以前用主席树做过,这次学整体二分来做.整体二分在yr大佬的指点下,终于大概懂了点了.对于二分能够解决的询问,如果有多个,那么如果支持离线处理的话,那么就可以使用整体二分了. 在这题二分可行的答案,根据这个答案,把询问操作丢在左右两个队列里面分别递归继续按这样处理.注释里写的很详细. 1 #include <iostream> 2 #include <cstdlib> 3 #

POJ 2104 K-th Number(分块+二分)

题目链接:http://poj.org/problem?id=2104 题目: Description You are working for Macrohard company in data structures department. After failing your previous task about key insertion you were asked to write a new data structure that would be able to return qu

整体二分初探 两类区间第K大问题 poj2104 &amp; hdu5412

看到好多讲解都把整体二分和$CDQ$分治放到一起讲 不过自己目前还没学会$CDQ$分治 就单独谈谈整体二分好了 先推荐一下$XHR$的 <浅谈数据结构题的几个非经典解法> 整体二分在当中有较为详细的讲解 先来说一下静态第$K$小的整体二分解法 $(POJ2104)$ 题目链接:http://poj.org/problem?id=2104 所谓整体二分 就是利用所有的询问相互独立而把它们$($此题没有修改操作$)$通过二分把它们分治进行处理 不妨先来考虑下一个简单易懂的$O(NlogS)$的排序

Poj 2104区间第k大(归并树)

题目链接 K-th Number Time Limit: 20000MS Memory Limit: 65536K Total Submissions: 36890 Accepted: 11860 Case Time Limit: 2000MS Description You are working for Macrohard company in data structures department. After failing your previous task about key ins

POJ 2104&amp;HDU 2665 Kth number(主席树入门+离散化)

K-th Number Time Limit: 20000MS   Memory Limit: 65536K Total Submissions: 50247   Accepted: 17101 Case Time Limit: 2000MS Description You are working for Macrohard company in data structures department. After failing your previous task about key inse