HDU 4251 --- 主席树(划分树是正解)
题意:查询区间中位数
思路:模板题,相当于区间第K大的数,主席树可以水过,但划分树是正解。但还没搞明白划分树,先上模板
#include <iostream>
#include <cstdio>
#include <cmath>
#include <cstring>
#include <cstdlib>
#include <string>
#include <vector>
#include <algorithm>
#include <set>
#define repu(i,a,b) for(int i=a;i<b;i++)
using namespace std;
#define N 1000010
#define ll long long
#define _cle(m, a) memset(m, a, sizeof(m))
const int MAXN = ;
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 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 Hash(int x)
{
return lower_bound(t+,t++m,x) - t;
}
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()
{
//freopen("in.txt","r", stdin);
//freopen("out.txt","w", stdout);
int kase = ;
while(scanf("%d",&n) == )
{
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,);
}
printf("Case %d:\n",kase++);
scanf("%d",&q);
while(q--)
{
int l,r,k;
scanf("%d%d",&l,&r);
k = (r-l)/+;
printf("%d\n",t[query(T[l],T[r+],k)]);
}
}
return ;
}
主席树
先上KB模板
//划分树
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
const int MAXN=;
int tree[][MAXN];//表示每层每个位置的值
int sorted[MAXN];//已经排序好的数
int toleft[][MAXN];//toleft[p][i]表示第i层从1到i有数分入左边
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++)//注意是l,不是one
if(tree[dep][i]<sorted[mid]) same--;
int lpos=l;
int 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+);
}
//查询区间第k大的数,[L,R]是大区间,[l,r]是要查询的小区间
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],newl=newr-(r-l-cnt);
return query(mid+,R,newl,newr,dep+,k-cnt);
}
}
int main(){
int n,m,t=;
while(~scanf("%d",&n)){
memset(tree,,sizeof(tree));
for(int i=;i<=n;i++){
scanf("%d",&tree[][i]);
sorted[i]=tree[][i];
}
sort(sorted+,sorted+n+);
build(,n,);
scanf("%d",&m);
printf("Case %d:\n",++t);
int s,t,k;
while(m--){
scanf("%d%d",&s,&t);
k=(t-s+)/;
printf("%d\n",query(,n,s,t,,k));
}
}
return ;
}
划分树
HDU 4251 --- 主席树(划分树是正解)的更多相关文章
- 归并树 划分树 可持久化线段树(主席树) 入门题 hdu 2665
如果题目给出1e5的数据范围,,以前只会用n*log(n)的方法去想 今天学了一下两三种n*n*log(n)的数据结构 他们就是大名鼎鼎的 归并树 划分树 主席树,,,, 首先来说两个问题,,区间第k ...
- hdu 2665 Kth number(划分树模板)
http://acm.hdu.edu.cn/showproblem.php?pid=2665 [ poj 2104 2761 ] 改变一下输入就可以过 http://poj.org/problem? ...
- HDU 2665 Kth number(划分树)
Kth number Time Limit: 15000/5000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others) Total S ...
- HDU 3473 Minimum Sum 划分树,数据结构 难度:1
http://acm.hdu.edu.cn/showproblem.php?pid=3473 划分树模板题目,需要注意的是划分树的k是由1开始的 划分树: 参考:http://blog.csdn.ne ...
- poj2104&&poj2761 (主席树&&划分树)主席树静态区间第k大模板
K-th Number Time Limit: 20000MS Memory Limit: 65536K Total Submissions: 43315 Accepted: 14296 Ca ...
- POJ 题目2761 Feed the dogs(主席树||划分树)
Feed the dogs Time Limit: 6000MS Memory Limit: 65536K Total Submissions: 16860 Accepted: 5273 De ...
- HDU 4417 - Super Mario ( 划分树+二分 / 树状数组+离线处理+离散化)
题意:给一个数组,每次询问输出在区间[L,R]之间小于H的数字的个数. 此题可以使用划分树在线解决. 划分树可以快速查询区间第K小个数字.逆向思考,判断小于H的最大的一个数字是区间第几小数,即是答案. ...
- hdu 2665 Kth number_划分树
题意:求区间[a,b]的第k大 因为多次询问要用到划分树 #include <iostream> #include<cstdio> #include<algorithm& ...
- HDU 4417 Super Mario(划分树)
Super Mario Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)Total ...
随机推荐
- js图片放大镜
<!doctype html><html><head><meta charset="utf-8"><style>#sma ...
- [Machine-Learning] 熟悉 Numpy
Numpy 是 Python 中的一个模块,主要用于处理数学和计算相关的问题,这里是一个入门的介绍. 导入 习惯上可以这样导入: import numpy as np 在 machine learni ...
- 执行大量的Redis命令,担心效率问题?用Pipelining试试吧~
参考的优秀文章 Request/Response protocols and RTT 来源 原来,系统中一个树结构的数据来源是Redis,由于数据增多.业务复杂,查询速度并不快.究其原因,是单次查询的 ...
- [问题2014A04] 解答
[问题2014A04] 解答 (1) 由条件可得 \(AB+BA=0\), 即 \(AB=-BA\), 因此 \[AB=A^2B=A(AB)=A(-BA)=-(AB)A=-(-BA)A=BA^2=B ...
- 2.4G高频PCB天线设计
2.4G高频PCB天线设计 本文博客链接:http://blog.csdn.net/jdh99,作者:jdh,转载请注明. 参考链接: http://bbs.rfeda.cn/read-htm-t ...
- 利用backtrace和objdump进行分析挂掉的程序
转自:http://blog.csdn.net/hanchaoman/article/details/5583457 汇编不懂,先把方法记下来. glibc为我们提供了此类能够dump栈内容的函数簇, ...
- [资源] Open source packages on SLAM
OpenSLAM http://openslam.org/ Most main stream open source slam resource can be found on OpenSLAM, w ...
- 《BI那点儿事》SQL Server 2008体系架构
Microsoft SQL Server是一个提供了联机事务处理.数据仓库.电子商务应用的数据库和数据分析的平台.体系架构是描述系统组成要素和要素之间关系的方式.Microsoft SQL Serve ...
- C语言细节——献给入门者(一)
C语言细节——献给入门者(一) 主题 输入输出需要注意的细节 首先我们要知道大致有scanf(),printf(),getchar(),putchar(),gets(),puts()这几种输入方式. ...
- Java:描述反射机制的作用?举几个反射的应用?
比较全的解释了:JAVA反射机制 JAVA反射机制是在运行状态中,对于任意一个类,都能够知道这个类的所有属性和方法:对于任意一个对象,都能够调用它的任意一个方法:这种动态获取的信息以及动态调用对象的方 ...