3524: [Poi2014]Couriers
Time Limit: 20 Sec Memory Limit: 256 MB
Submit: 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行,每行两个数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
0
4
HINT
【数据范围】
n,m≤500000
2016.7.9重设空间,但未重测!
Source
主席树裸题
1 #include<iostream> 2 #include<cstring> 3 #include<cstdio> 4 #include<cstdlib> 5 #include<cmath> 6 #include<algorithm> 7 using namespace std; 8 struct data { 9 int ls,rs,sum; 10 }a[10000000]; 11 int root[500005]; 12 int n,sz=0,m; 13 void insert(int l,int r,int x,int &y,int val) { 14 y=++sz; 15 a[y].sum=a[x].sum+1; 16 if(l==r) return; 17 a[y].ls=a[x].ls;a[y].rs=a[x].rs; 18 int mid=(l+r)>>1; 19 if(val<=mid) insert(l,mid,a[x].ls,a[y].ls,val); 20 else insert(mid+1,r,a[x].rs,a[y].rs,val); 21 return ; 22 } 23 int query(int l,int r,int x,int y,int k) { 24 if(l==r) return l; 25 int mid=(l+r)>>1; 26 if(a[a[y].ls].sum-a[a[x].ls].sum>k) return query(l,mid,a[x].ls,a[y].ls,k); 27 if(a[a[y].rs].sum-a[a[x].rs].sum>k) return query(mid+1,r,a[x].rs,a[y].rs,k); 28 return 0; 29 } 30 int main() { 31 scanf("%d%d",&n,&m); 32 for(int i=1;i<=n;i++) { 33 int t; 34 scanf("%d",&t); 35 insert(1,n,root[i-1],root[i],t); 36 } 37 for(int i=1;i<=m;i++) { 38 int l,r; 39 scanf("%d%d",&l,&r); 40 int t=query(1,n,root[l-1],root[r],(r-l+1)/2); 41 printf("%d\n",t); 42 } 43 }
时间: 2024-10-13 22:31:15