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次蒙特卡罗,正确率就为1-(1/2)^k,
  复杂度为O(kmlogn)。

  主席树做法见 LINK

【代码】

#include <cstdio>
#include <algorithm>
#include <vector>
using namespace std;
const int N=500010;
vector<int> pos[N];
int a[N],l,r,n,m;
int main(){
    while(~scanf("%d%d",&n,&m)){
        for(int i=1;i<=n;i++)pos[i].clear();
        for(int i=1;i<=n;i++){
            scanf("%d",&a[i]);
            pos[a[i]].push_back(i);
        }
        while(m--){
            scanf("%d%d",&l,&r);
            int len=r-l+1,find=0;
            for(int k=1;k<=20;k++){
                int u=a[l+rand()%len];
                int st=lower_bound(pos[u].begin(),pos[u].end(),l)-pos[u].begin();
                int en=upper_bound(pos[u].begin(),pos[u].end(),r)-pos[u].begin();
                if((en-st)*2>len){find=u;break;}
            }if(find)printf("%d\n",find);
            else puts("0");
        }
    }return 0;
}
时间: 2024-11-08 20:45:03

BZOJ 3524 [Poi2014]Couriers(二分+蒙特卡罗)的相关文章

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 可持久化线段树

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

3524: [Poi2014]Couriers -- 主席树

3524: [Poi2014]Couriers Time Limit: 20 Sec  Memory Limit: 256 MB 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

【BZOJ】3524 [POI2014] Couriers(主席树)

题目 传送门:QWQ 传送到洛谷QWQ 分析 把求区间第k大的改一改就ok了. 代码 1 #include <bits/stdc++.h> 2 using namespace std; 3 const int N=500010; 4 int root[N*40], ls[N*40], rs[N*40], sum[N*40]; 5 int n, m, newp; 6 7 void add(int l,int r,int x,int& cur,int cur1) 8 { 9 cur=++n

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[

[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行,

[Poi2014]Couriers

bzoj3524: [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

【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