主席树 Couriers

【bzoj3524/2223】[Poi2014]Couriers

2014年4月19日1,2571

Description

给一个长度为n的序列a。1≤a[i]≤n。
m组询问,每次询问一个区间[l,r],是否存在一个数在[l,r]中出现的次数大于(r-l+1)/2。如果存在,输出这个数,否则输出0。

Input

第一行两个数n,m。
第二行n个数,a[i]。
接下来m行,每行两个数l,r,表示询问[l,r]这个区间。

Output

m行,每行对应一个答案。/*

#include<iostream>
#include<cstdio>
using namespace std;
int sum[10000010],ls[10000010],rs[100000010],root[500010];
int n,m,sz;
inline int read()
{
char ch=getchar();
while(!(ch>=‘0‘&&ch<=‘9‘))ch=getchar();
int x=0;
while(ch>=‘0‘&&ch<=‘9‘){x=x*10+(ch-‘0‘);ch=getchar();}
return x;
}
void update(int l,int r,int x,int &y,int v)
{
y=++sz;
sum[y]=sum[x]+1;
if(l==r)
return;
ls[y]=ls[x];
rs[y]=rs[x];
int mid=(l+r)>>1;
if(v<=mid)
update(l,mid,ls[x],ls[y],v);
else
update(mid+1,r,rs[x],rs[y],v);
}
int que(int L,int R)
{
int l=1,r=n,mid,x,y,tmp=((R-L+1)>>1);
x=root[L-1];
y=root[R];
for(;l!=r;)
{
if(sum[y]-sum[x]<=tmp)
return 0;
mid=(l+r)>>1;
if(sum[ls[y]]-sum[ls[x]]>tmp)
{
y=ls[y];
x=ls[x];
r=mid;
}
else if(sum[rs[y]]-sum[rs[x]]>tmp)
{
y=rs[y];
x=rs[x];
l=mid+1;
}
else
return 0;
}
return l;
}
int main()
{
n=read();m=read();
for(int i=1;i<=n;i++)
{
int x;
x=read();
update(1,n,root[i-1],root[i],x);
}
for(int i=0;i<m;i++)
{
int l,r;
l=read();
r=read();
printf("%d\n",que(l,r));
}
return 0;
}*/

时间: 2024-08-24 19:27:50

主席树 Couriers的相关文章

[静态主席树]Couriers

题目描述 给一个长度为n的序列a.1≤a[i]≤n.m组询问,每次询问一个区间[l,r],是否存在一个数在[l,r]中出现的次数大于(r-l+1)/2.如果存在,输出这个数,否则输出0. 输入 第一行两个数n,m(n,m≤500000).第二行n个数,a[i].接下来m行,每行两个数l,r,表示询问[l,r]这个区间. 输出 m行,每行对应一个答案. 样例输入 7 5 1 1 3 2 3 4 3 1 3 1 4 3 7 1 7 6 6 样例输出 1 0 3 0 4 思路:建立可持久化权值线段树A

BZOJ 3524: [Poi2014]Couriers( 主席树 )

卡我空间.... 这道题应该是主席树入门题...无修改 , 离散化都不用...出题人业界良心啊 一开始的空白树我 build 出来结果就多了整整 2n 个 Node , 然后就 MLE 了... ( 双倍经验 , 另一道见上图 ) ---------------------------------------------------------------------------------------------- #include<cstdio> #include<cstring&g

[BZOJ2223][BZOJ3524][Poi2014]Couriers 主席树

3524: [Poi2014]Couriers Time Limit: 20 Sec  Memory Limit: 256 MBSubmit: 2436  Solved: 960[Submit][Status][Discuss] Description 给一个长度为n的序列a.1≤a[i]≤n.m组询问,每次询问一个区间[l,r],是否存在一个数在[l,r]中出现的次数大于(r-l+1)/2.如果存在,输出这个数,否则输出0. Input 第一行两个数n,m.第二行n个数,a[i].接下来m行,

BZOJ 3524 POI 2014 Couriers 主席树

题目大意 给出一个序列,问一段区间内有没有出现过一半以上的数字. 思路 用主席树取区间出来,在权值线段树上找. CODE #define _CRT_SECURE_NO_WARNINGS #include <cstdio> #include <cstring> #include <iostream> #include <algorithm> #define MAX 500010 #define MAXR 10000010 using namespace std

【复习笔记】主席树

昨天在写带修改主席树的时候,咸鱼zcysky发现自己似乎根本不会写主席树 于是正好找个空复习下-- 主席树的原理不用我扯了,主席树为啥能求k大,大概在它可以用历史版本存下区间的前缀和,求的时候差分下就能提出我要求的区间. 不过这么搞的话不要忘了离散化. 1.kth number 就是上面的裸题,不要手贱写bits就好. 1 #include<iostream> 2 #include<cstdio> 3 #define N 100010 4 #include<algorithm

【算法】主席树

这是一篇有关主席树的总结 主席树是什么? 对于原序列的每一个前缀[1···i]建立出一棵线段树维护值域上每个数出现的次数,则其树是可减的 PS:本篇随笔对于主席树的基本内容并没有深刻讲解,主要说明它的一些用法 其实就是很多一堆大量的权值线段树 (什么是权值线段树?就是每个节点维护不是位置,而是权值,比如 \([1,4]\) 维护的就是权值等于1到权值等于4的信息) 而且这些线段树还隐含了一个前缀和的功能 最简单的就是一个数列,长度为 \(n\) ,那么就建 \(n\) 棵权值线段树,第 \(i\

[bzoj3524][Poi2014]Couriers_主席树

Couriers bzoj-3524 Poi-2014 题目大意:给定n个数的序列,询问区间内是否存在一个在区间内至少出现了(区间长度>>1)次的数.如果有,输出该数,反之输出0. 注释:$1\le n,m\le 5\cdot 10^5$. 想法:主席树裸题. 主流做法就是弄一个Existence数组询问有没有这样的数,然后查询区间中位数即可. 但是可以在query的时候强行查询,因为没有输出0,直接输出即可. 最后,附上丑陋的代码... ... #include <iostream&g

[poj2104]可持久化线段树入门题(主席树)

解题关键:离线求区间第k小,主席树的经典裸题: 对主席树的理解:主席树维护的是一段序列中某个数字出现的次数,所以需要预先离散化,最好使用vector的erase和unique函数,很方便:如果求整段序列的第k小,我们会想到离散化二分和线段树的做法, 而主席树只是保存了序列的前缀和,排序之后,对序列的前缀分别做线段树,具有差分的性质,因此可以求任意区间的第k小,如果主席树维护索引,只需要求出某个数字在主席树中的位置,即为sort之后v中的索引:若要求第k大,建树时反向排序即可 1 #include

【BZOJ 3551】[ONTAK2010] Peaks加强版 Kruskal重构树+树上倍增+主席树

这题真刺激...... I.关于Kruskal重构树,我只能开门了,不过补充一下那玩意还是一棵满二叉树.(看一下内容之前请先进门坐一坐) II.原来只是用树上倍增求Lca,但其实树上倍增是一种方法,Lca只是他的一种应用,他可以搞各种树上问题,树上倍增一般都会用到f数组. |||.我们跑出来dfs序就能在他的上面进行主席树了. IV.别忘了离散. V.他可能不连通,我一开始想到了,但是我觉得出题人可能会是好(S)人(B),但是...... #include <cstdio> #include