[cf643G]Choosing Ads

首先对于$p>50$,有经典的做法,即不断删去区间中不同的两数,最终剩下的即为出现次数超过一半的数(或没有),用线段树维护即可

那么对于$p\le 50$,类似的,即删去区间中不同的$\lfloor \frac{100}{p}\rfloor+1$个数,那么最终剩下的$\lfloor \frac{100}{p}\rfloor$个数中必然存在一个答案(或没有),同样可以维护

时间复杂度为$o(25n\log_{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("\n");
86         }
87     }
88 }
View Code

 

posted @ 2020-10-20 13:46  PYWBKTDA  阅读(111)  评论(0编辑  收藏  举报