考虑求区间绝对众数的方法
维护当前值和次数
如果当前这个值
否则
如果
这样保证最后得到的一定是出现次数的
出现次数的类似
线段树维护每个区间的
合并2个区间只需要把2边的前个拿来合并
仍然是对的
#include<bits/stdc++.h>
using namespace std;
const int RLEN=1<<20|1;
inline char gc(){
static char ibuf[RLEN],*ib,*ob;
(ob==ib)&&(ob=(ib=ibuf)+fread(ibuf,1,RLEN,stdin));
return (ob==ib)?EOF:*ib++;
}
#define gc getchar
inline int read(){
char ch=gc();
int res=0,f=1;
while(!isdigit(ch))f^=ch=='-',ch=gc();
while(isdigit(ch))res=(res+(res<<2)<<1)+(ch^48),ch=gc();
return f?res:-res;
}
#define ll long long
#define re register
#define pii pair<int,int>
#define fi first
#define se second
#define pb push_back
#define cs const
#define bg begin
inline void chemx(int &a,int b){a<b?a=b:0;}
inline void chemn(int &a,int b){a>b?a=b:0;}
cs int N=150005;
cs int C=11;
struct Val{
int val,siz;
friend inline bool operator <(cs Val &a,cs Val &b){
return a.siz>b.siz;
}
};
int n,q,a[N],S,P;
struct node{
int len;Val v[C];
node(){len=0;}
inline void init(int val,int siz){
len=1,v[1].val=val,v[1].siz=siz;
}
friend inline node operator +(cs node &a,cs node &b){
node c=a;
for(int i=1;i<=b.len;i++){
bool fg=0;
for(int j=1;j<=c.len;j++)
if(b.v[i].val==c.v[j].val){
c.v[j].siz+=b.v[i].siz,fg=1;
}
if(!fg)c.v[++c.len]=b.v[i];
}
if(c.len>S){
sort(c.v+1,c.v+c.len+1);
for(int i=c.len;i>S;i--)
for(int j=1;j<=i;j++)
c.v[j].siz-=c.v[i].siz;
while(c.len&&c.v[c.len].siz<=0)c.len--;
}
return c;
}
};
namespace Seg{
node tr[N<<2];
int tag[N<<2];
#define lc (u<<1)
#define rc ((u<<1)|1)
#define mid ((l+r)>>1)
inline void pushup(int u){
tr[u]=tr[lc]+tr[rc];
}
inline void pushnow(int u,int l,int r,int k){
tag[u]=k,tr[u].init(k,r-l+1);
}
inline void pushdown(int u,int l,int r){
if(!tag[u])return;
pushnow(lc,l,mid,tag[u]);
pushnow(rc,mid+1,r,tag[u]);
tag[u]=0;
}
void build(int u,int l,int r){
if(l==r){
tr[u].init(a[l],1);return ;
}
build(lc,l,mid),build(rc,mid+1,r);
pushup(u);
}
void update(int u,int l,int r,int st,int des,int k){
if(st<=l&&r<=des)return pushnow(u,l,r,k);
pushdown(u,l,r);
if(st<=mid)update(lc,l,mid,st,des,k);
if(mid<des)update(rc,mid+1,r,st,des,k);
pushup(u);
}
node query(int u,int l,int r,int st,int des){
if(st<=l&&r<=des)return tr[u];
pushdown(u,l,r);
node res;
if(des<=mid)res=query(lc,l,mid,st,des);
else if(mid<st)res=query(rc,mid+1,r,st,des);
else res=query(lc,l,mid,st,des)+query(rc,mid+1,r,st,des);
pushup(u);return res;
}
}
int main(){
n=read(),q=read(),P=read(),S=100/P;
for(int i=1;i<=n;i++)a[i]=read();
Seg::build(1,1,n);
while(q--){
int op=read(),l=read(),r=read();
if(op==1){
int id=read();
Seg::update(1,1,n,l,r,id);
}
else{
node res=Seg::query(1,1,n,l,r);
cout<<res.len<<" ";
for(int i=1;i<=res.len;i++)cout<<res.v[i].val<<" ";puts("");
}
}
}