• [cf643G]Choosing Ads


    首先对于$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 }
    View Code
  • 相关阅读:
    bzoj 1232 [Usaco2008Nov]安慰奶牛cheer
    bzoj 1237 [SCOI2008]配对 贪心+dp
    缺8数
    缺8数
    Binary GCD algorithm
    Binary GCD algorithm
    HDU1576 A/B (解法二)【试探法】
    HDU1576 A/B (解法二)【试探法】
    I00002 打印九九乘法表
    I00002 打印九九乘法表
  • 原文地址:https://www.cnblogs.com/PYWBKTDA/p/13846082.html
Copyright © 2020-2023  润新知