题解 P7261 [COCI2009-2010#3] PATULJCI
iMya_nlgau · · 题解
因为这是一道黄题,所以不用主席树或者莫队这些算法。
我们对每种颜色开一个 vector 存下该颜色出现位置的下标,这样给定一个区间 v[c] 表示颜色
upper_bound(v[c].begin(),v[c].end(),r)-lower_bound(v[c].begin(),v[c].end(),l);
就是
然后再考虑,如果一个颜色
所以对于每个询问
时间复杂度
#include<cstdio>
#include<algorithm>
#include<cstring>
#include<cctype>
#include<vector>
#include<cstdlib>
#include<ctime>
using namespace std;
inline int read(){
int x=0; char c=getchar();
while(!isdigit(c)) c=getchar();
while(isdigit(c)) x=x*10+(c^'0'),c=getchar();
return x;
}
const int maxn=3e5+10;
const int maxm=1e4+10;
int n,c,m,a[maxn];
vector<int> v[maxm];
inline int query(int l,int r){
for(int t=1;t<=50;t++){
int p=l+rand()%(r-l+1);
int res=upper_bound(v[a[p]].begin(),v[a[p]].end(),r)
-lower_bound(v[a[p]].begin(),v[a[p]].end(),l);
if(res>(r-l+1)/2) return a[p];
}
return -1;
}
int main(){
srand((unsigned)time(NULL));
n=read(),c=read();
for(int i=1;i<=n;i++)
a[i]=read(),v[a[i]].push_back(i);
for(int i=1;i<=c;i++) v[i].push_back(n+1);
m=read();
while(m--){
int l=read(),r=read();
int ans=query(l,r);
if(~ans) printf("yes %d\n",ans);
else puts("no");
}
return 0;
}