bzoj 3524 主席树 解题报告
2017-07-17 21:43
417 查看
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 51 1 3 2 3 4 3
1 3
1 4
3 7
1 7
6 6
Sample Output
10
3
0
4
HINT
【数据范围】n,m≤500000
Source
By Dzy思路
又有m组询问,每次对于一个区间[l,r]问是否存在一个数在[l,r]中出现的次数大于(r-l+1)/2。如果存在,输出这个数,否则输出0。主席树
代码
!!!!!我没权限#include<cstdio> #include<iostream> #include<cstring> #include<algorithm> #include<cmath> #include<queue> using namespace std; const int N=500005; int n,m,l,r,x,cnt,rt ,son[2][N*20],sum[N*20]; void Insert(int rl,int rn,int l,int r,int v) { sum[rn]=sum[rl]+1; if(l==r)return; int mid = (l+r)/2; if(mid>=v) { son[1][rn]=son[1][rl]; son[0][rn]=++cnt; Insert(son[0][rl],son[0][rn],l,mid,v); } else { son[0][rn]=son[0][rl]; son[1][rn]=++cnt; Insert(son[1][rl],son[1][rn],mid+1,r,v); } } int query(int rl,int rn,int l,int r,int k) { if(l==r)return l; int mid=(l+r)/2; if(sum[son[0][rn]]-sum[son[0][rl]]>k) return query(son[0][rl],son[0][rn],l,mid,k); if(sum[son[1][rn]]-sum[son[1][rl]]>k) return query(son[1][rl],son[1][rn],mid+1,r,k); return 0; } int main(void) { scanf("%d%d",&n,&m); for(int i=1;i<=n;i++) rt[i]=++cnt; for(int i=1;i<=n;i++) { scanf("%d",&x); Insert(rt[i-1],rt[i],1,n,x); } for(int i=1;i<=m;i++) { scanf("%d%d",&l,&r); printf("%d\n",query(rt[l-1],rt[r],1,n,(r-l+1)/2)); } return 0; }
相关文章推荐
- BZOJ 3524 主席树(随机数水过) 解题报告
- BZOJ 3119 贪心 解题报告
- BZOJ 2201 期望DP 解题报告
- bzoj 1661: [Usaco2006 Nov]Big Square 巨大正方形 解题报告
- [BZOJ1911][BZOJ1912][BZOJ1913]APIO2010解题报告
- BZOJ 2118 数论+最短路(SPFA) 解题报告
- bzoj 1036 树链剖分 解题报告
- BZOJ 1455 可并堆(左偏树) 解题报告
- BZOJ 1588 TREAP 解题报告
- bzoj 3696 化合物 解题报告
- BZOJ4009: [HNOI2015]接水果 解题报告
- BZOJ4010: [HNOI2015]菜肴制作 解题报告
- [BZOJ 4815] [Cqoi2017]小Q的表格 解题报告
- 【BZOJ3524/2223】[Poi2014]Couriers 主席树
- BZOJ 3566 [SHOI 2014] 树上期望DP 解题报告
- bzoj 3524/2223(主席树)
- BZOJ3524[Couriers] 不带修改主席树裸题
- BZOJ 3781 莫队 解题报告
- 【主席树】BZOJ3524 [Poi2014]Couriers
- BZOJ 2565 Manacher 解题报告