Couriers(bzoj 3524)

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行,每行对应一个答案。

Sample Input

7 5

1 1 3 2 3 4 3

1 3

1 4

3 7

1 7

6 6

Sample Output

1

0

3

0

4

HINT

【数据范围】

n,m≤500000

/*
  借此写一写对于主席树的认识。
  我们在做数据结构题目的过程中可能会用到多次更新前的某一个状态,所以我们要想一个办法储存下每一个时刻的树。
  暴力做n棵树?这样的时间和空间都会华丽的GG。
  我们会发现对于一个状态,相对于他前一个状态的改变是很少的,那是不是意味着可以多加几个点就可以,而不是暴力建一棵新树。
  答案是肯定的。我们再加点的过程中只要利用前一棵树的信息和新状态的信息,在创立几个新点就行了。 

  PS:我在一个问题上搞了好几个小时,关于新树的大小和原来的树是否相同的问题,貌似很明显是相同的,然而我傻,以为不相同,导致mengbi了很长时间。
*/
#include<cstdio>
#include<iostream>
#define N 500010
using namespace std;
int root[N],ls[N*20],rs[N*20],sum[N*20],cnt,n,m;
void add(int pre,int &k,int l,int r,int v){
    k=++cnt;
    sum[k]=sum[pre]+1;
    if(l==r) return;
    ls[k]=ls[pre];rs[k]=rs[pre];
    int mid=l+r>>1;
    if(v<=mid) add(ls[pre],ls[k],l,mid,v);
    else add(rs[pre],rs[k],mid+1,r,v);
}
int query(int x,int y){//两个时刻
    int l=1,r=n,tmp=(y-x+1)/2;
    x=root[x-1];y=root[y];
    while(l!=r){
        if(sum[y]-sum[x]<=tmp)return 0;
        int mid=l+r>>1;
        if(sum[ls[y]]-sum[ls[x]]>tmp){
            r=mid;x=ls[x];y=ls[y];
        }
        else if(sum[rs[y]]-sum[rs[x]]>tmp){
            l=mid+1;x=rs[x];y=rs[y];
        }
        else return 0;
    }
    return l;
}
int main(){
    scanf("%d%d",&n,&m);
    for(int i=1;i<=n;i++){
        int x;scanf("%d",&x);
        add(root[i-1],root[i],1,n,x);
    }
    for(int i=1;i<=m;i++){
        int x,y;scanf("%d%d",&x,&y);
        printf("%d\n",query(x,y));
    }
    return 0;
}
时间: 2024-10-19 12:08:08

Couriers(bzoj 3524)的相关文章

BZOJ 3524: [Poi2014]Couriers

3524: [Poi2014]Couriers Time Limit: 20 Sec  Memory Limit: 256 MBSubmit: 1905  Solved: 691[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: [Poi2014]Couriers( 主席树 )

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

BZOJ 3524 [Poi2014]Couriers(二分+蒙特卡罗)

[题目链接] http://www.lydsy.com/JudgeOnline/problem.php?id=3524 [题目大意] 给一个长度为n的序列a.1≤a[i]≤n. m组询问,每次询问一个区间[l,r],是否存在一个数在[l,r]中出现的次数大于(r-l+1)/2. 如果存在,输出这个数,否则输出0. [题解] 我们可以在[l,r]中随机一个位置检验这个位置上数是不是答案, 检测方法可以在数组中保存每个数在序列中的不同位置,二分即可 选中答案的概率为1/2,我们做k次蒙特卡罗,正确率

BZOJ 3524 [Poi2014]Couriers 可持久化线段树

题意:链接 方法:可持久化线段树. 解析: 可持久化数据结构好神啊,感觉都好玄妙的感觉. 首先建树的目的就是建立一棵权值树,维护的是在L,R里某些权值的数的出现个数.然后呢,对于1~n每个节点建一棵树,并且是基于前一棵树的基础上的.然后对于每一次的新值我们只需要update一次,并且连接一下原来的树? 神犇们不是说这种结构就是一堆线段树连啊连就出来了吗. 查询的时候呢?有一些小改变,据说是以二分为基础的查询. 神犇们发明这种数据结构的时候,就发现了这种数据结构里的所有线段树是可以相减的这种性质,

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

【bzoj 3524】[Poi2014]Couriers

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行,每行对应一个答案. Sample Input 7 5 1 1 3 2 3 4 3 1 3 1 4 3 7 1 7 6 6 Sample Output 1 0 3

[BZOJ 3524] kur 绝对众数

题意 给定长度为 n 的序列 A = {a[1], a[2], ..., a[n]} . m 次询问, 求区间 [l, r] 的绝对众数. n, m <= 100000 . 分析 性质1. 如果存在绝对众数, 那么中位数一定是绝对众数. 性质2. 不同数两两匹配, 最后剩下来的是绝对众数. 建立可持久化线段树, 根据 性质1 , 找中位数有多少个. 我们用 性质2 带来的摩尔投票法进行对拍. 实现 一般来说, 如果要找中位数, 都用 n+1 >> 1 , 而不是 n >> 1

bzoj 3524 [POI2014]KUR-Couriers (主席树)

题目大意:给你一个序列,求某个区间出现次数大于一半的数是什么 主席树裸题,刷刷水题提升自信= = 1 #include <cstdio> 2 #include <cstring> 3 #include <algorithm> 4 #define ll long long 5 #define il inline 6 #define N 500100 7 using namespace std; 8 //re 9 int n,m,tot; 10 int a[N],root[

【BZOJ】【3524】【POI2014】Couriers

可持久化线段树 裸可持久化线段树,把区间第K大的rank改成num即可……(往儿子走的时候不减少) 苦逼的我……MLE了一次(N*30),RE了一次(N*10)……数组大小不会开…… 最后开成N*20的过了 1 /************************************************************** 2 Problem: 3524 3 User: Tunix 4 Language: C++ 5 Result: Accepted 6 Time:5752 ms