POJ2104 K-th Number —— 静态区间第k小
题目链接:http://poj.org/problem?id=2104
| Time Limit: 20000MS | Memory Limit: 65536K | |
| Total Submissions: 64277 | Accepted: 22615 | |
| Case Time Limit: 2000MS | ||
Description
That is, given an array a[1...n] of different integer numbers, your program must answer a series of questions Q(i, j, k) in the form: "What would be the k-th number in a[i...j] segment, if this segment was sorted?"
For example, consider the array a = (1, 5, 2, 6, 3, 7, 4). Let the question be Q(2, 5, 3). The segment a[2...5] is (5, 2, 6, 3). If we sort this segment, we get (2, 3, 5, 6), the third number is 5, and therefore the answer to the question is 5.
Input
The second line contains n different integer numbers not exceeding 109 by their absolute values --- the array for which the answers should be given.
The following m lines contain question descriptions, each description consists of three numbers: i, j, and k (1 <= i <= j <= n, 1 <= k <= j - i + 1) and represents the question Q(i, j, k).
Output
Sample Input
7 3
1 5 2 6 3 7 4
2 5 3
4 4 1
1 7 3
Sample Output
5
6
3
Hint
Source
划分树:
#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <vector>
#include <cmath>
#include <queue>
#include <stack>
#include <map>
#include <string>
#include <set>
using namespace std;
typedef long long LL;
const int INF = 2e9;
const LL LNF = 9e18;
const int mod = 1e9+;
const int MAXN = 1e5+; int tree[][MAXN];
int sorted[MAXN];
int toleft[][MAXN]; void build(int l, int r, int dep)
{
if(l==r) return;
int mid = (l+r)>>;
int same = mid-l+;
for(int i = l; i<=r; i++)
if(tree[dep][i]<sorted[mid])
same--; int lpos = l, rpos = mid+;
for(int i = l; i<=r; i++)
{
if(tree[dep][i]<sorted[mid])
tree[dep+][lpos++] = tree[dep][i];
else if(tree[dep][i]==sorted[mid] && same>)
{
tree[dep+][lpos++] = tree[dep][i];
same--;
}
else
tree[dep+][rpos++] = tree[dep][i];
toleft[dep][i] = toleft[dep][l-] + lpos - l;
} build(l, mid, dep+);
build(mid+, r, dep+);
} 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)>>;
int cnt = toleft[dep][r] - toleft[dep][l-]; if(cnt>=k)
{
int newl = L + toleft[dep][l-] - toleft[dep][L-];
int newr = newl + cnt - ;
return query(L, mid, newl, newr, dep+, k);
}
else
{
int newr = r + toleft[dep][R] - toleft[dep][r];
int newl = newr - (r-l-cnt);
return query(mid+, R, newl, newr, dep+, k-cnt);
}
} int main()
{
int n, m;
while(scanf("%d%d",&n,&m)!=EOF)
{
memset(tree, , sizeof(tree));
for(int i = ; i<=n; i++)
{
scanf("%d",&tree[][i]);
sorted[i] = tree[][i];
}
sort(sorted+, sorted++n);
build(, n, );
int s, t, k;
while(m--)
{
scanf("%d%d%d",&s,&t,&k);
printf("%d\n", query(,n,s,t,,k));
}
}
return ;
}
主席树(循环):
#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <vector>
#include <cmath>
#include <queue>
#include <stack>
#include <map>
#include <string>
#include <set>
using namespace std;
typedef long long LL;
const int INF = 2e9;
const LL LNF = 9e18;
const int MOD = 1e9+;
const int MAXN = 1e5+;
const int M = MAXN*; int n, q, m, tot;
int a[MAXN], t[MAXN];
int T[MAXN], lson[M], rson[M], c[M]; void Init_hash()
{
for(int i = ; i<=n; i++)
t[i] = a[i];
sort(t+,t++n);
m = unique(t+,t++n)-(t+);
} int hash(int x)
{
return lower_bound(t+,t++m, x)-t;
} int build(int l, int r)
{
int root = tot++;
c[root] = ;
if(l!=r)
{
int mid = (l+r)>>;
lson[root] = build(l,mid);
rson[root] = build(mid+,r);
}
return root;
} int update(int root, int pos, int val)
{
int newroot = tot++, tmp = newroot;
c[newroot] = c[root] + val;
int l = , r = m;
while(l<r)
{
int mid = (l+r)>>;
if(pos<=mid)
{
lson[newroot] = tot++; rson[newroot] = rson[root];
newroot = lson[newroot]; root = lson[root];
r = mid;
}
else
{
rson[newroot] = tot++; lson[newroot] = lson[root];
newroot = rson[newroot]; root = rson[root];
l = mid + ;
}
c[newroot] = c[root] + val;
}
return tmp;
} int query(int left_root, int right_root, int k)
{
int l = , r = m;
while(l<r)
{
int mid = (l+r)>>;
if(c[lson[left_root]]-c[lson[right_root]]>=k)
{
r = mid;
left_root = lson[left_root];
right_root = lson[right_root];
}
else
{
l = mid + ;
k -= c[lson[left_root]]-c[lson[right_root]];
left_root = rson[left_root];
right_root = rson[right_root];
}
}
return l;
} int main()
{
while(scanf("%d%d",&n,&q)==)
{
tot = ;
for(int i = ; i<=n; i++)
scanf("%d",&a[i]);
Init_hash();
T[n+] = build(,m);
for(int i = n; i; i--)
{
int pos = hash(a[i]);
T[i] = update(T[i+],pos,);
}
while(q--)
{
int l, r, k;
scanf("%d%d%d",&l,&r,&k);
printf("%d\n", t[query(T[l],T[r+],k)]);
}
}
}
主席树(递归):
#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <vector>
#include <cmath>
#include <queue>
#include <stack>
#include <map>
#include <string>
#include <set>
using namespace std;
typedef long long LL;
const int INF = 2e9;
const LL LNF = 9e18;
const int MOD = 1e9+;
const int MAXN = 1e5+;
const int M = MAXN*; int n, q, m, tot;
int a[MAXN], t[MAXN];
int T[MAXN], lson[M], rson[M], c[M]; void Init_hash()
{
for(int i = ; i<=n; i++)
t[i] = a[i];
sort(t+,t++n);
m = unique(t+,t++n)-(t+);
} int hash(int x)
{
return lower_bound(t+,t++m, x)-t;
} int build(int l, int r)
{
int root = tot++;
c[root] = ;
if(l!=r)
{
int mid = (l+r)>>;
lson[root] = build(l,mid);
rson[root] = build(mid+,r);
}
return root;
} int update(int root, int l, int r, int pos, int val)
{
int newroot = tot++;
if(l==r)
{
c[newroot] = c[root] + val;
return newroot;
}
int mid = (l+r)>>;
if(pos<=mid)
{
lson[newroot] = update(lson[root],l,mid,pos,val);
rson[newroot] = rson[root];
}
else
{
rson[newroot] = update(rson[root],mid+,r,pos,val);
lson[newroot] = lson[root];
}
c[newroot] = c[lson[newroot]] + c[rson[newroot]];
return newroot;
} int query(int left_root, int right_root, int l, int r, int k)
{
if(l==r) return l; int mid = (l+r)>>;
if(c[lson[left_root]]-c[lson[right_root]]>=k)
return query(lson[left_root],lson[right_root],l,mid,k);
else
return query(rson[left_root],rson[right_root],mid+,r,k-(c[lson[left_root]]-c[lson[right_root]]));
} int main()
{
while(scanf("%d%d",&n,&q)!=EOF)
{
tot = ;
for(int i = ; i<=n; i++)
scanf("%d",&a[i]);
Init_hash();
T[n+] = build(,m);
for(int i = n; i; i--)
{
int pos = hash(a[i]);
T[i] = update(T[i+],,m,pos,);
}
while(q--)
{
int l, r, k;
scanf("%d%d%d",&l,&r,&k);
printf("%d\n", t[query(T[l],T[r+],,m,k)]);
}
}
}
POJ2104 K-th Number —— 静态区间第k小的更多相关文章
- POJ2104 K-th Number 静态区间第k最值 平方分割
干掉这道题的那一刻,我只想说:我终于**的AC了!!! 最终内存1344K,耗时10282ms,比起归并树.划分树以及其他各种黑科技,这个成绩并不算光彩⊙﹏⊙ 但至少,从最初的无数次TLE到最终的AC ...
- poj2104&&poj2761 (主席树&&划分树)主席树静态区间第k大模板
K-th Number Time Limit: 20000MS Memory Limit: 65536K Total Submissions: 43315 Accepted: 14296 Ca ...
- HDU3473--Minimum Sum(静态区间第k大)
Minimum Sum Time Limit: 16000/8000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others)Tota ...
- 数据结构2 静态区间第K大/第K小
给定数组$A[1...N]$, 区间$[L,R]$中第$K$大/小的数的指将$A[L...R]$中的数从大到小/从小到大排序后的第$K$个. "静态"指的是不带修改. 这个问题有多 ...
- Dynamic Rankings || 动态/静态区间第k小(主席树)
JYF大佬说,一星期要写很多篇博客才会有人看 但是我做题没有那么快啊QwQ Part1 写在前面 区间第K小问题一直是主席树经典题=w=今天的重点是动态区间第K小问题.静态问题要求查询一个区间内的第k ...
- 主席树初步学习笔记(可持久化数组?静态区间第k大?)
我接触 OI也快1年了,然而只写了3篇博客...(而且还是从DP跳到了主席树),不知道我这个机房吊车尾什么时候才能摸到大佬们的脚后跟orz... 前言:主席树这个东西,可以说是一种非常畸形的数据结构( ...
- 静态区间第k大(归并树)
POJ 2104为例 思想: 利用归并排序的思想: 建树过程和归并排序类似,每个数列都是子树序列的合并与排序. 查询过程,如果所查询区间完全包含在当前区间中,则直接返回当前区间内小于所求数的元素个数, ...
- 主席树学习笔记(静态区间第k大)
题目背景 这是个非常经典的主席树入门题——静态区间第K小 数据已经过加强,请使用主席树.同时请注意常数优化 题目描述 如题,给定N个整数构成的序列,将对于指定的闭区间查询其区间内的第K小值. 输入输出 ...
- 主席树(静态区间第k大)
前言 如果要求一些数中的第k大值,怎么做? 可以先就这些数离散化,用线段树记录每个数字出现了多少次. ... 那么考虑用类似的方法来求静态区间第k大. 原理 假设现在要有一些数 我们可以对于每个数都建 ...
随机推荐
- nginx/iptables动态IP黑白名单实现方案
nginx/iptables动态IP黑白名单实现方案 一.手动封IP步骤 1.Nginx手动封IP 1.获取各个IP访问次数 awk '{print $1}' nginx.access.log |so ...
- 移动端弹窗 layer.js 使用
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8&quo ...
- OSX:设置用户默认浏览器
近期我们遇到的情况是,须要统一设置用户的默认浏览器为Google Chrome.而系统默认的是Safari. 这个设置是系统Launch Services基于用户管理的. 意思就是说,即便是改动了系统 ...
- SpringMVC:前台jsp页面和后台传值
前台jsp页面和后台传值的几种方式: 不用SpringMVC自带的标签 前台---->后台,通过表单传递数据(): 1.jsp页面代码如下, modelattribute 有没有都行 < ...
- jenkins构建一个go项目
Jenkins安装 最低配置: 不少于256M内存,不低于1G磁盘,jdk版本>=8 安装jdk1.8 yum install -y java-1.8.0-openjdk wget -O / ...
- Win8.1离线安装.Net Framework 3.5
在线安装太慢了! 只要一个命令搞掂 不希望使用Internet连接,可以使用DISM (部署映像服务和管理工具)离线部署 .NET Framework 3.5 1. Win+X选择命令提示符(管 ...
- Leet Code OJ 237. Delete Node in a Linked List [Difficulty: Easy]
题目: Write a function to delete a node (except the tail) in a singly linked list, given only access t ...
- DisplayPort的时钟隐藏和时钟恢复
转:DisplayPort的时钟隐藏和时钟恢复 无时钟线的视频数据传输是DP协议的一大特点,将时钟信号隐藏在数据中是传输协议的设计趋势.时钟恢复技术也是DP芯片设计的关键技术.在这说一下在发送端时钟是 ...
- Key-Value键值存储原理初识(NOSQL)
NO-Sql数据库:Not Only不仅仅是SQL 定义:非关系型数据库:NoSQL用于超大规模数据的存储.(例如谷歌或Facebook每天为他们的用户收集万亿比特的数据).这些类型的数据存储不需要固 ...
- 兔子--改动Android Studio的快捷键,改动成eclipse的快捷键
仅仅须要2步 watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvdTAxMzQyNTUyNw==/font/5a6L5L2T/fontsize/400/fill ...