传送门: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。
题解:感觉这种题,随便搞啊,莫队什么的,主席树也可以啊,就当复习主席树咯
代码:
1 #include<iostream> 2 #include<algorithm> 3 #include<cstring> 4 #include<cstdio> 5 #include<cmath> 6 #define maxn 500010 7 using namespace std; 8 int root[maxn],ls[maxn*20],rs[maxn*20]; 9 int sum[maxn*20]; 10 int n,m; 11 int sz; 12 int read() 13 { 14 int x=0; char ch; bool bo=0; 15 while (ch=getchar(),ch<'0'||ch>'9') if (ch=='-') bo=1; 16 while (x=x*10+ch-'0',ch=getchar(),ch>='0'&&ch<='9'); 17 if (bo) return -x; return x; 18 } 19 void ins(int l,int r,int x,int &y,int val) 20 { 21 y=++sz; 22 sum[y]=sum[x]+1; 23 if (l==r) return; 24 ls[y]=ls[x],rs[y]=rs[x]; 25 int mid=(l+r)>>1; 26 if (val<=mid) ins(l,mid,ls[x],ls[y],val); 27 else ins(mid+1,r,rs[x],rs[y],val); 28 } 29 int query(int L,int R) 30 { 31 int l=1,r=n,mid,x,y,tmp; 32 x=root[L-1],y=root[R]; 33 tmp=(R-L+1)/2; 34 //cout<<" "<<tmp<<endl; 35 while (l!=r) 36 { 37 if (sum[y]-sum[x]<=tmp) return 0; 38 int mid=(l+r)>>1; 39 if (sum[ls[y]]-sum[ls[x]]>tmp) 40 { 41 r=mid; y=ls[y],x=ls[x]; 42 } 43 else 44 if (sum[rs[y]]-sum[rs[x]]>tmp) 45 { 46 l=mid+1,y=rs[y],x=rs[x]; 47 } 48 else return 0; 49 } 50 return l; 51 } 52 53 int main() 54 { 55 n=read(); m=read(); 56 for (int i=1; i<=n; i++) 57 { 58 int x=read(); 59 ins(1,n,root[i-1],root[i],x); 60 } 61 for (int i=1; i<=m ;i++) 62 { 63 int l=read(),r=read(); 64 int ans=query(l,r); 65 printf("%d ",ans); 66 } 67 }