BZOJ3524 [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。

题解:感觉这种题,随便搞啊,莫队什么的,主席树也可以啊,就当复习主席树咯

代码:

 1 #include<iostream>
 2 #include<algorithm>
 3 #include<cstring>
 4 #include<cstdio>
 5 #include<cmath>
 6 #define maxn 500010
 7 using namespace std;
 8 int root[maxn],ls[maxn*20],rs[maxn*20];
 9 int sum[maxn*20];
10 int n,m;
11 int sz;
12 int read()
13 {
14     int x=0; char ch; bool bo=0;
15     while (ch=getchar(),ch<‘0‘||ch>‘9‘) if (ch==‘-‘) bo=1;
16     while (x=x*10+ch-‘0‘,ch=getchar(),ch>=‘0‘&&ch<=‘9‘);
17     if (bo) return -x; return x;
18 }
19 void ins(int l,int r,int x,int &y,int val)
20 {
21     y=++sz;
22     sum[y]=sum[x]+1;
23     if (l==r) return;
24     ls[y]=ls[x],rs[y]=rs[x];
25     int mid=(l+r)>>1;
26     if (val<=mid) ins(l,mid,ls[x],ls[y],val);
27     else ins(mid+1,r,rs[x],rs[y],val);
28 }
29 int query(int L,int R)
30 {
31     int l=1,r=n,mid,x,y,tmp;
32     x=root[L-1],y=root[R];
33     tmp=(R-L+1)/2;
34     //cout<<"         "<<tmp<<endl;
35     while (l!=r)
36     {
37         if (sum[y]-sum[x]<=tmp) return 0;
38         int mid=(l+r)>>1;
39         if (sum[ls[y]]-sum[ls[x]]>tmp)
40         {
41             r=mid; y=ls[y],x=ls[x];
42         }
43         else
44         if (sum[rs[y]]-sum[rs[x]]>tmp)
45         {
46             l=mid+1,y=rs[y],x=rs[x];
47         }
48         else return 0;
49     }
50     return l;
51 }
52
53 int main()
54 {
55     n=read(); m=read();
56     for (int i=1; i<=n; i++)
57     {
58         int x=read();
59         ins(1,n,root[i-1],root[i],x);
60     }
61     for (int i=1; i<=m ;i++)
62     {
63         int l=read(),r=read();
64         int ans=query(l,r);
65         printf("%d\n",ans);
66     }
67 }

时间: 2024-10-10 15:28:39

BZOJ3524 [Poi2014]Couriers的相关文章

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

bzoj3524 [Poi2014]Couriers/2223 [Coci 2009]PATULJCI

题目链接1 题目链接2 主席树模板题 两题有细节不同 1 #include<algorithm> 2 #include<iostream> 3 #include<cstdlib> 4 #include<cstring> 5 #include<cstdio> 6 #include<string> 7 #include<cmath> 8 #include<ctime> 9 #include<queue>

[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

[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

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

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

bzoj3524/2223 [Poi2014]Couriers

传送门:http://www.lydsy.com/JudgeOnline/problem.php?id=3524 http://www.lydsy.com/JudgeOnline/problem.php?id=2223 [题解] 由于出现次数超过区间长度的一半的数最多只有1个,所以就可以分两半找了.. # include <stdio.h> # include <string.h> # include <iostream> # include <algorithm

【bzoj3524】[Poi2014]Couriers

题目描述 给一个长度为n的序列a.1≤a[i]≤n.m组询问,每次询问一个区间[l,r],是否存在一个数在[l,r]中出现的次数大于(r-l+1)/2.如果存在,输出这个数,否则输出0. 输入 第一行两个数n,m.第二行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 题解 主席树 同bzoj2223,也不需要离散化. b