首先对于$p>50$,有经典的做法,即不断删去区间中不同的两数,最终剩下的即为出现次数超过一半的数(或没有),用线段树维护即可
那么对于$ple 50$,类似的,即删去区间中不同的$lfloor frac{100}{p} floor+1$个数,那么最终剩下的$lfloor frac{100}{p} floor$个数中必然存在一个答案(或没有),同样可以维护
时间复杂度为$o(25nlog_{2}n)$,可以通过
1 #include<bits/stdc++.h> 2 using namespace std; 3 #define N 150005 4 #define L (k<<1) 5 #define R (L+1) 6 #define mid (l+r>>1) 7 #define vii vector<pair<int,int> > 8 #define fi first 9 #define se second 10 vii empty,v,f[N<<2]; 11 int n,m,p,a[N],tag[N<<2]; 12 vii merge(vii x,vii y){ 13 v.clear(); 14 for(int i=0,j=0;(i<x.size())||(j<y.size());){ 15 pair<int,int> o; 16 if ((i<x.size())&&((j==y.size())||(x[i].fi<y[j].fi)))o=x[i++]; 17 else o=y[j++]; 18 if ((v.size())&&(o.fi==v[v.size()-1].fi))v[v.size()-1].se+=o.se; 19 else v.push_back(o); 20 } 21 while (v.size()>=p){ 22 int mn=v[0].se; 23 for(int i=1;i<p;i++)mn=min(mn,v[i].se); 24 for(int i=p-1;i>=0;i--){ 25 v[i].se-=mn; 26 if (!v[i].se)v.erase(v.begin()+i); 27 } 28 } 29 return v; 30 } 31 void upd(int k,int l,int r,int x){ 32 tag[k]=x; 33 f[k].clear(); 34 f[k].push_back(make_pair(x,r-l+1)); 35 } 36 void down(int k,int l,int r){ 37 if (tag[k]){ 38 upd(L,l,mid,tag[k]); 39 upd(R,mid+1,r,tag[k]); 40 tag[k]=0; 41 } 42 } 43 void build(int k,int l,int r){ 44 if (l==r){ 45 f[k].push_back(make_pair(a[l],1)); 46 return; 47 } 48 build(L,l,mid); 49 build(R,mid+1,r); 50 f[k]=merge(f[L],f[R]); 51 } 52 void update(int k,int l,int r,int x,int y,int z){ 53 if ((l>y)||(x>r))return; 54 if ((x<=l)&&(r<=y)){ 55 upd(k,l,r,z); 56 return; 57 } 58 down(k,l,r); 59 update(L,l,mid,x,y,z); 60 update(R,mid+1,r,x,y,z); 61 f[k]=merge(f[L],f[R]); 62 } 63 vii query(int k,int l,int r,int x,int y){ 64 if ((l>y)||(x>r))return empty; 65 if ((x<=l)&&(r<=y))return f[k]; 66 down(k,l,r); 67 return merge(query(L,l,mid,x,y),query(R,mid+1,r,x,y)); 68 } 69 int main(){ 70 scanf("%d%d%d",&n,&m,&p); 71 p=100/p+1; 72 for(int i=1;i<=n;i++)scanf("%d",&a[i]); 73 build(1,1,n); 74 for(int i=1;i<=m;i++){ 75 int p,l,r,x; 76 scanf("%d%d%d",&p,&l,&r); 77 if (p==1){ 78 scanf("%d",&x); 79 update(1,1,n,l,r,x); 80 } 81 else{ 82 v=query(1,1,n,l,r); 83 printf("%d ",v.size()); 84 for(int j=0;j<v.size();j++)printf("%d ",v[j].fi); 85 printf(" "); 86 } 87 } 88 }