• 【Codeforces 643G】—Choosing Ads(线段树)


    传送门

    考虑O(n)O(n)求区间绝对众数的方法
    维护当前值vv和次数kk
    如果当前这个值̸=v,k ot =v,k--
    否则k++k++
    如果k<0,v=a[i]k<0,v=a[i]
    这样保证最后得到的一定是出现次数>n/2>n/2

    出现次数>n/p>n/p的类似
    线段树维护每个区间的
    合并2个区间只需要把2边的前100/p100/p个拿来合并
    仍然是对的

    #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("");
    		}
    	}
    }
    
  • 相关阅读:
    WebService相关
    远程连接db2数据库
    修改VNC分辨率大小
    java面向对象的核心思想
    小故障排查
    使用IntelliJ IDEA开发java web
    WebService概述
    Qt开发之信号槽机制
    用SoapUI 测试Web Service
    剑指offer:滑动窗口的最大值
  • 原文地址:https://www.cnblogs.com/stargazer-cyk/p/12328540.html
Copyright © 2020-2023  润新知