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[N];
11 struct Seg{
12     int ls,rs,sum;
13 }seg[N*30];
14
15 int gc()
16 {
17     int rett=0,fh=1;char p=getchar();
18     while(p<‘0‘||p>‘9‘){if(p==‘-‘)fh=-1;p=getchar();}
19     while(p>=‘0‘&&p<=‘9‘){rett=(rett<<3)+(rett<<1)+p-‘0‘;p=getchar();}
20     return rett*fh;
21 }
22 il void pushup(int rt){seg[rt].sum=seg[seg[rt].ls].sum+seg[seg[rt].rs].sum;}
23 void build(int l,int r,int rt)
24 {
25     if(l==r) return;
26     int mid=(l+r)>>1;
27     seg[rt].ls=++tot,build(l,mid,tot);
28     seg[rt].rs=++tot,build(mid+1,r,tot);
29 }
30 void update(int x,int l,int r,int rt1,int rt2,int val)
31 {
32     if(l==r) {seg[rt2].sum+=val;return;}
33     int mid=(l+r)>>1;
34     if(x<=mid){
35         if(!seg[rt2].ls||seg[rt2].ls==seg[rt1].ls){
36             seg[rt2].ls=++tot,seg[seg[rt2].ls].sum=seg[seg[rt1].ls].sum;
37             if(!seg[rt2].rs) seg[rt2].rs=seg[rt1].rs;
38         }update(x,l,mid,seg[rt1].ls,seg[rt2].ls,val);
39     }else{
40         if(!seg[rt2].rs||seg[rt2].rs==seg[rt1].rs){
41             seg[rt2].rs=++tot,seg[seg[rt2].rs].sum=seg[seg[rt1].rs].sum;
42             if(!seg[rt2].ls) seg[rt2].ls=seg[rt1].ls;
43         }update(x,mid+1,r,seg[rt1].rs,seg[rt2].rs,val);
44     }pushup(rt2);
45 }
46 int query(int l,int r,int rt1,int rt2,int len)
47 {
48     if(l==r) return l;
49     int mid=(l+r)>>1;
50     if(seg[seg[rt2].ls].sum-seg[seg[rt1].ls].sum>=len)
51         return query(l,mid,seg[rt1].ls,seg[rt2].ls,len);
52     if(seg[seg[rt2].rs].sum-seg[seg[rt1].rs].sum>=len)
53         return query(mid+1,r,seg[rt1].rs,seg[rt2].rs,len);
54     return 0;
55 }
56
57 int main()
58 {
59     //freopen("data.in","r",stdin);
60     scanf("%d%d",&n,&m);
61     for(int i=1;i<=n;i++) a[i]=gc();
62     root[0]=++tot,build(1,n,tot);
63     for(int i=1;i<=n;i++)
64         root[i]=++tot,update(a[i],1,n,root[i-1],root[i],1);
65     int x,y;
66     while(m--)
67     {
68         x=gc(),y=gc();
69         printf("%d\n",query(1,n,root[x-1],root[y],(y-x+1)/2+1));
70     }
71     return 0;
72 }

原文地址:https://www.cnblogs.com/guapisolo/p/9697043.html

时间: 2024-10-08 23:35:55

bzoj 3524 [POI2014]KUR-Couriers (主席树)的相关文章

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( 主席树 )

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

[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: [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(二分+蒙特卡罗)

[题目链接] 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 4571][Scoi2016]美味(主席树)

Description 一家餐厅有 n 道菜,编号 1...n ,大家对第 i 道菜的评价值为 ai(1≤i≤n).有 m 位顾客,第 i 位顾客的期 望值为 bi,而他的偏好值为 xi .因此,第 i 位顾客认为第 j 道菜的美味度为 bi XOR (aj+xi),XOR 表示异或 运算.第 i 位顾客希望从这些菜中挑出他认为最美味的菜,即美味值最大的菜,但由于价格等因素,他只能从第 li 道到第 ri 道中选择.请你帮助他们找出最美味的菜. Solution 按位贪心,每次通过查询一段区间是

【BZOJ 3772】精神污染 主席树+欧拉序

这道题的内存-------真·精神污染---.. 这道题的思路很明了,我们就是要找每一个路径包含了多少其他路径那么就是找,有多少路径的左右端点都在这条路径上,对于每一条路径,我们随便选定一个端点作为第一关键字,另一个作为第二关键字,于是就有了两维限制,按照主席树的一般思路,我们把建树顺序作为一维,然后在里面维护另一维,那么我们在外面限制第一关键字,就是在树上建主席树,查询减LCA,在里面的话我们把每个点作为第一关键字对应的第二关键字,放入主席树,而主席树维护的是欧拉序区间,所以我们每次查询只用查

【BZOJ 3123】 [Sdoi2013]森林 主席树启发式合并

我们直接按父子关系建主席树,然后记录倍增方便以后求LCA,同时用并查集维护根节点,而且还要记录根节点对应的size,用来对其启发式合并,然后每当我们合并的时候我们都要暴力拆小的一部分重复以上部分,总时间复杂度为O(n*log),因为每个的节点只会作为小的部分合并,因此他所在的一小部分至少变大2倍,对于每一个节点他作为被合并方最多log次,因此其复杂度为O(n*log),而这个是绝对跑不满还差很多的,我们视他为无常数就好了,当然这一切都是建立在无拆分操作的基础之上,只要有了拆分启发式合并的复杂度就