题目大意:给一个数列,每次询问一个区间内有没有一个数出现次数超过一半
裸的主席树啊,只需要每次走大于一半的那面就行了,两边都不符合就是没有啦!
#include<iostream>
#include<cstdio>
using namespace std;
int rt[500001],n,m;
int ch[10000001][2];
int w[10000001],cnt;
void pup(int x) {w[x]=w[ch[x][0]]+w[ch[x][1]];}
void addnew(int l,int r,int x,int &y,int v)
{
cnt++;
y=cnt;
if(l==r)
{
w[y]=w[x]+1;
return;
}
int mid=(l+r)>>1;
ch[y][1]=ch[x][1];ch[y][0]=ch[x][0];
if(v<=mid) addnew(l,mid,ch[x][0],ch[y][0],v);
else addnew(mid+1,r,ch[x][1],ch[y][1],v);
pup(y);
}
int check(int ll,int rr)
{
int x=rt[ll-1],y=rt[rr],t=(rr-ll+1)/2;
int l=1,r=n,mid;
while(l<r)
{
if(w[y]-w[x]<=t) return 0;
// cout<<w[ch[y][0]]<<' '<<w[ch[x][0]]<<' '<<w[ch[y][1]]<<' '<<w[ch[x][1]]<<endl;
mid=(l+r)>>1;
if(w[ch[y][0]]-w[ch[x][0]]>t)
{
r=mid;
x=ch[x][0];
y=ch[y][0];
}
else if(w[ch[y][1]]-w[ch[x][1]]>t)
{
l=mid+1;
x=ch[x][1];
y=ch[y][1];
}
else return 0;
}
return l;
}
int main()
{
scanf("%d%d",&n,&m);
int i,j,x,y;
for(i=1;i<=n;i++)
{
scanf("%d",&x);
addnew(1,n,rt[i-1],rt[i],x);
}
for(i=1;i<=m;i++)
{
scanf("%d%d",&x,&y);
printf("%d\n",check(x,y));
}
}