POJ2104 ---(区间第K 大)
来源:互联网 发布:考勤工资软件 编辑:程序博客网 时间:2024/05/21 10:17
学习划分树和主席树练得模板题。
题目 :
就是区间第K 大了。
目前只会划分树和主席树了。
Code:
/* 划分树//#include <bits/stdc++.h>#include <iostream>#include <algorithm>#define lson l,m,rt<<1#define rson m+1,r,rt<<1|1using namespace std;const int maxn = 100000 +69;int tree[30][maxn]; //记录树第dep层序列int sorted[maxn]; //原始序列排序后int toleft[30][maxn]; //记录树第dep层 前 i 个有多少进入左区间。void Build(int l, int r, int dep) { if(l ==r) return ; int mid = (l + r) >> 1; int same = mid -l+1; for(int i = l; i <= r; ++i) if(tree[dep][i] < sorted[mid]) same--; int lpos = l; int rpos = mid + 1; for(int i = l; i <= r; ++i) { if(tree[dep][i] < sorted[mid]) tree[dep+1][lpos++] = tree[dep][i]; else if (tree[dep][i] == sorted[mid] && same > 0) tree[dep+1][lpos++] = tree[dep][i], same--; else tree[dep+1][rpos++] = tree[dep][i]; toleft[dep][i] = toleft[dep][l-1] + lpos -l; } Build(l, mid, dep+1); Build(mid+1,r,dep+1);}int query(int L, int R, int l,int r,int dep, int k) { if(l == r) return tree[dep][l]; int mid = (L+R)>>1; int cnt = toleft[dep][r] - toleft[dep][l-1]; //区间有多少数进入左区间 if(cnt >= k) { //递归左树 int newl = L + toleft[dep][l-1]-toleft[dep][L-1]; int newr = newl + cnt - 1; return query(L,mid, newl, newr, dep+1, k); } else { //递归右树 int newr = r + toleft[dep][R] - toleft[dep][r]; int newl = newr - (r-l-cnt); return query(mid+1, R, newl, newr, dep+1,k-cnt); }}int main() { ios::sync_with_stdio(false); int n, m; while(cin >> n >> m) { for(int i = 1; i <= n; ++i) { cin >> tree[0][i]; sorted[i] = tree[0][i]; } sort(sorted+1, sorted+n+1); Build(1,n,0); while(m--) { int l, r, k; cin >> l >> r >> k; cout << query(1,n,l,r,0,k) << endl; } } return 0;}*/// 主席树, 动态的话就套个树状数组可以了。#include <iostream>#include <algorithm>using namespace std;const int maxn = 100000 + 131;struct Node { int lpos, rpos; int w; Node() { lpos = rpos = w = 0; }};Node T[maxn * 30];int a[maxn], b[maxn], p[maxn], root[maxn], sz;bool cmp(int i, int j) { return a[i] < a[j];}int n, m;void Insert(int &i, int l, int r,int x) { T[++sz] = T[i]; i = sz; T[i].w++; if(l == r) return ; int m = (l + r) >> 1; if(x <= m) Insert(T[i].lpos,l,m,x); else Insert(T[i].rpos, m+1,r,x);}int Query(int i, int j, int l,int r,int k) { if(l == r) return l; int t = T[T[j].lpos].w - T[T[i].lpos].w; int m = (l + r) >> 1; if(t >= k) return Query(T[i].lpos, T[j].lpos,l,m,k); else return Query(T[i].rpos,T[j].rpos,m+1,r,k-t);}int main() { ios::sync_with_stdio(false); while(cin >> n >> m) { root[0] = 0; for(int i = 1; i <= n; ++i) { cin >> a[i]; p[i] = i; } sort(p+1,p+1+n,cmp); for(int i = 1; i <= n; ++i) b[p[i]] = i; sz = 0; for(int i = 1; i <= n; ++i) { root[i] = root[i-1]; Insert(root[i],1,n,b[i]); } while(m--) { int l, r, k; cin >> l >> r >> k; int t = Query(root[l-1],root[r],1,n,k); cout << a[p[t]] <<endl; } } return 0;}
0 0
- POJ2104 ---(区间第K 大)
- poj2104 区间第K大
- poj2761&&poj2104 主席树(静态区间第K大)
- poj2104(区间第k大+离散化)
- poj2104 主席树区间第k大
- POJ2104 区间第k大(版本1)
- 【poj2104】区间第k大(版本1)
- poj2104 (线段树求区间第k大)
- POJ2104 POJ2761 区间第K大 主席树
- 区间第k大(版本1)POJ2104(BSOI1722)
- 可持久化线段树(主席树)(图文并茂详解)【poj2104】【区间第k大】
- poj2104区间K大 主席树
- POJ2104-K-th Number-区间第k大-可持久化线段树/主席树
- 【poj2104】不带修改的区间第k大 主席树
- 查询区间第k大 POJ2104 暴力 or 划分树 or 归并树
- poj2104 K-th Number(静态区间k大,主席树)
- 主席树经典题目 区间k大值 poj2104
- 区间第K大
- pat 1043. Is It a Binary Search Tree (25)
- Python爬虫实践:从中文歌词库抓取歌词
- Linux Shell编程入门
- openstack的用户(user), 租户(tenant), 角色(role)概念区分
- Unity快速实现回合制游戏
- POJ2104 ---(区间第K 大)
- hello word
- C#语法灵活运用之排列组合算法
- JavaScript Object.prototype.constructor属性详解
- JAVA 反射API
- bzoj 2287(背包dp)
- PyMySQL-在Python 3.x下连接MySQL数据库的方法
- Python 小甲鱼教程 课后练习39
- vs2010安装“LNK1123: 转换到 COFF 期间失败: 文件无效或损坏”解决方法