zoukankan      html  css  js  c++  java
  • [Ynoi2019模拟赛]Yuno loves sqrt technology III

    题目传送门

    题意

    • 给定序列,要求在线查询 ([l,r]) 中众数出现次数。

    Sol

    看到 ( ext{Ynoi}) 考虑分块。(

    常规套路,先预处理每组连续块内的答案。

    (sqrt n) 个块,对于每个块作为左端点有 (O(n)) 的处理,预处理 (O(nsqrt n))

    考虑询问操作。

    对于囊括在其中的块,可以直接拿来用。

    剩余边界上最多 (2sqrt n) 个元素。

    考虑对于每个边界元素进行查询。

    然鹅现在已经 (O(msqrt n)) 了,似乎查询需要很小的复杂度才行诶qaq。

    考虑利用上面已处理的答案。

    对一个元素,考虑它向右答案位的同值元素是否在答案区间内。

    由于每次更新答案会 (+1),而答案最多会 (+2sqrt n),于是更新答案复杂度也为 (sqrt n)

    那么我们还需考虑 (O(1)) 解决查询同值元素的位置。

    考虑 ( ext{vector}) 记录同值元素位置,再随便拿个东西记该数在 ( ext{vector}) 中位置即可。记得离散化。

    总复杂度 ((n+m)sqrt n)

    ( ext{Code})

    // wish to get better qwq
    
    #include<bits/stdc++.h>
    #define re register int
    #define pb push_back
    
    using namespace std;
    typedef long long ll;
    
    template <typename T> inline void rd(T &x){
    	int fl=1;x=0;char c=getchar();
    	for(;!isdigit(c);c=getchar()) if(c=='-') fl=-fl;
    	for(;isdigit(c);c=getchar()) x=(x<<3)+(x<<1)+c-'0';
    	x*=fl;
    }
    void wr(int x){
    	if(x<0) x=-x,putchar('-');
    	if(x<10) putchar(x+'0');
    	if(x>9) wr(x/10),putchar(x%10+'0');
    }
    
    inline int mx(int x,int y){return x<y?y:x;}
    
    // ---------- IO ---------- //
    
    const int N=5e5+5,SQ=735;
    int n,m,sum[SQ][SQ],a[N],b[N],ans,sub[N],len=SQ-5,cnt[N];
    vector<int> ran[N];
    
    // ---------- Sqrt ---------- //
    
    inline int block(int x){return (x-1)/len+1;}
    inline int L(int x){return (x-1)*len+1;}
    inline int R(int x){return x*len;}
    
    inline void init(){
    	int lst=block(n);
    	for(re i=1;i<=lst;i++){
    		memset(cnt,0,sizeof(cnt));
    		for(re j=i;j<=lst;j++){
    			sum[i][j]=sum[i][j-1];
    			int qaq=L(j),qwq=R(j);
    			for(re k=qaq;k<=qwq;k++) sum[i][j]=mx(sum[i][j],++cnt[a[k]]);
    		}
    	}
    }
    
    inline int query(int l,int r){
    	int tot=0;
    	if(block(l)==block(r)){
    		for(re i=l;i<=r;i++) cnt[a[i]]=0;
    		for(re i=l;i<=r;i++) tot=mx(tot,++cnt[a[i]]);
    		return tot;
    	}
    	tot=sum[block(l)+1][block(r)-1];
    	int qaq=R(block(l));
    	for(re i=l;i<=qaq;i++){
    		int nw=sub[i]+tot;
    		while(nw<ran[a[i]].size()&&ran[a[i]][nw]<=r) tot++,nw++;
    	}
    	qaq=L(block(r));
    	for(re i=qaq;i<=r;i++){
    		int nw=sub[i]-tot;
    		while(nw>=0&&ran[a[i]][nw]>=l) tot++,nw--;
    	}
    	return tot;
    }
    
    // ---------- Operation ---------- //
    
    int main(){
    //	freopen(".in","r",stdin);
    //	freopen(".out","w",stdout);
    	rd(n);rd(m);
    	for(re i=1;i<=n;i++) rd(a[i]),b[i]=a[i];
    	sort(b+1,b+n+1);
    	for(re i=1;i<=n;i++) a[i]=lower_bound(b+1,b+n+1,a[i])-b,ran[a[i]].pb(i),sub[i]=ran[a[i]].size()-1;
    	init();
    	for(re i=1,u,v;i<=m;i++){
    		rd(u);rd(v);
    		u^=ans;v^=ans;
    		wr(ans=query(u,v));puts("");
    	}
    	return 0;
    }
    
    // ---------- Main ---------- //
    

    改进了码风果然更好看了qwq

  • 相关阅读:
    封装tip控件
    Javascirpt中创建对象的几种方式
    使用Servlet上传文件
    Struts2 基本配置
    使用JQuery实现手风琴布局
    winform下自绘提示框风格窗体
    环形进度条
    Oracle中获取当前时间半小时前的时间
    JSTL+MyEclipse8.5+Tomcat配置
    使用CSS和jQuery实现对话框
  • 原文地址:https://www.cnblogs.com/danieljiang/p/yunolovessqrttechnologyIII.html
Copyright © 2011-2022 走看看