BZOJ3524: [Poi2014]Couriers

3524: [Poi2014]Couriers

Time Limit: 20 Sec  Memory Limit: 128 MB
Submit: 466  Solved: 141
[Submit][Status]

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


Source

By Dzy

题解:

主席树bug一样存在。。。

由于满足区间相减的性质,所以我们类似于树状数组可以得到区间[l,r]的权值信息,然后这题就裸了。。。

代码:

  1 #include<cstdio>
  2 
  3 #include<cstdlib>
  4 
  5 #include<cmath>
  6 
  7 #include<cstring>
  8 
  9 #include<algorithm>
 10 
 11 #include<iostream>
 12 
 13 #include<vector>
 14 
 15 #include<map>
 16 
 17 #include<set>
 18 
 19 #include<queue>
 20 
 21 #include<string>
 22 
 23 #define inf 1000000000
 24 
 25 #define maxn 10000000+1000
 26 
 27 #define maxm 500000+1000
 28 
 29 #define eps 1e-10
 30 
 31 #define ll long long
 32 
 33 #define pa pair<int,int>
 34 
 35 #define for0(i,n) for(int i=0;i<=(n);i++)
 36 
 37 #define for1(i,n) for(int i=1;i<=(n);i++)
 38 
 39 #define for2(i,x,y) for(int i=(x);i<=(y);i++)
 40 
 41 #define for3(i,x,y) for(int i=(x);i>=(y);i--)
 42 
 43 #define mod 1000000007
 44 
 45 using namespace std;
 46 
 47 inline int read()
 48 
 49 {
 50 
 51     int x=0,f=1;char ch=getchar();
 52 
 53     while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
 54 
 55     while(ch>='0'&&ch<='9'){x=10*x+ch-'0';ch=getchar();}
 56 
 57     return x*f;
 58 
 59 }
 60 int n,m,tot,root[maxm],ls[maxn],rs[maxn],s[maxn];
 61 void update(int l,int r,int x,int &y,int z)
 62 {
 63     y=++tot;
 64     s[y]=s[x]+1;
 65     if(l==r)return;
 66     ls[y]=ls[x];rs[y]=rs[x];
 67     int mid=(l+r)>>1;
 68     if(z<=mid)update(l,mid,ls[x],ls[y],z);else update(mid+1,r,rs[x],rs[y],z);
 69 }
 70 int query(int x,int y)
 71 {
 72     int l=1,r=n,mid,xx=root[x-1],yy=root[y],tmp=(y-x+1)>>1;
 73     while(l!=r)
 74     {
 75         mid=(l+r)>>1;
 76         if(s[yy]-s[xx]<tmp)return 0;
 77         if(s[ls[yy]]-s[ls[xx]]>tmp){r=mid;xx=ls[xx];yy=ls[yy];}
 78         else if(s[rs[yy]]-s[rs[xx]]>tmp){l=mid+1;xx=rs[xx];yy=rs[yy];}
 79         else return 0;
 80     }
 81     return l;
 82 }
 83 
 84 int main()
 85 
 86 {
 87 
 88     freopen("input.txt","r",stdin);
 89 
 90     freopen("output.txt","w",stdout);
 91 
 92     n=read();m=read();
 93     for1(i,n)
 94     {
 95         int x=read();update(1,n,root[i-1],root[i],x);
 96     }
 97     while(m--)
 98     {
 99         int x=read(),y=read();
100         printf("%d\n",query(x,y));
101     }
102 
103     return 0;
104 
105 }
View Code

 

posted @ 2014-09-25 18:59  ZYF-ZYF  Views(230)  Comments(0Edit  收藏  举报