BZOJ3524: [Poi2014]Couriers
题解: 直接主席树查询即可
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 | #include <bits/stdc++.h> const int MAXN=5e5+10; using namespace std; typedef struct node{ int l,r,sum; }node; node d[MAXN*21]; int a[MAXN],cnt,rt[MAXN]; void update( int &x, int y, int l, int r, int t){ x=++cnt;d[x]=d[y];d[x].sum++; if (l==r) return ; int mid=(l+r)>>1; if (t<=mid)update(d[x].l,d[y].l,l,mid,t); else update(d[x].r,d[y].r,mid+1,r,t); } int ans,key; void querty( int x, int y, int l, int r){ if (l==r){ans=l; return ;} int mid=(l+r)>>1; if (d[d[y].l].sum-d[d[x].l].sum>key)querty(d[x].l,d[y].l,l,mid); if (d[d[y].r].sum-d[d[x].r].sum>key)querty(d[x].r,d[y].r,mid+1,r); } int main(){ int n,m; scanf ( "%d%d" ,&n,&m); for ( int i=1;i<=n;i++) scanf ( "%d" ,&a[i]),update(rt[i],rt[i-1],1,n,a[i]); int l,r; for ( int i=1;i<=m;i++){ scanf ( "%d%d" ,&l,&r);key=(r-l+1)/2; ans=0;querty(rt[l-1],rt[r],1,n); printf ( "%d\n" ,ans); } return 0; } |
3524: [Poi2014]Couriers
Time Limit: 20 Sec Memory Limit: 256 MBSubmit: 2825 Solved: 1150
[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行,每行两个数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
1 1 3 2 3 4 3
1 3
1 4
3 7
1 7
6 6
Sample Output
1
0
3
0
4
0
3
0
4
HINT
【数据范围】
n,m≤500000
2016.7.9重设空间,但未重测!
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步