• BZOJ 2724: [Violet 6]蒲公英


    题目大意:

    求区间众数,强制在线。

    题解:

    考虑分块,一段区间的众数一定在整块的众数和两边多出来的数中。

    可能是众数的数有O(sqrt(n))个,然后我们考虑查询这些数在区间中出现了几次。

    把原来的序列中相同数字的下标从小到大扔进vector中,然后二分就能求每个数在区间中出现了几次。

    找一个出现次数最大的就行了。

    复杂度O(nsqrt(n)log(n))

    代码

    #include<cstdio>
    #include<algorithm>
    #include<cstring>
    #include<vector>
    #include<map>
    using namespace std;
    int id,n,m,block,ans,f[505][505],cnt[100005],v[100005],belong[1000005],val[1000005];
    map<int,int> mp;
    vector<int> vec[1000005];
    void pre(int x){
    	memset(cnt,0,sizeof(cnt));
    	int maxx=0,ans=0;
    	for (int i=(x-1)*block+1; i<=n; i++){
    		cnt[v[i]]++;
    		int t=belong[i];
    		if (cnt[v[i]]>maxx || (cnt[v[i]]==maxx && val[v[i]]<val[ans])){
    			ans=v[i];
    			maxx=cnt[v[i]];
    		}
    		f[x][t]=ans;
    	}
    }
    int query(int l,int r,int x){
    	int t=upper_bound(vec[x].begin(),vec[x].end(),r)-lower_bound(vec[x].begin(),vec[x].end(),l);
    	return t;
    }
    int calc(int l,int r){
    	int ans=f[belong[l]+1][belong[r]-1];
    	int maxx=query(l,r,ans);
    	for (int i=l; i<=min(belong[l]*block,r); i++){
    		int x=query(l,r,v[i]);
    		if (x>maxx || (x==maxx && val[v[i]]<val[ans])) {
    			ans=v[i];
    			maxx=x;
    		}
    	}
    	if (belong[l]!=belong[r]){
    		for (int i=(belong[r]-1)*block+1; i<=r; i++){
    			int x=query(l,r,v[i]);
    			if (x>maxx || (x==maxx && val[v[i]]<val[ans])) {
    				ans=v[i];
    				maxx=x;
    			}
    		}
    	}
    	return ans;
    }
    int main(){
    	scanf("%d%d",&n,&m);
    	block=200;
    	int ans=0;
    	for (int i=1; i<=n; i++){
    		scanf("%d",&v[i]);
    		if (!mp[v[i]]){
    			mp[v[i]]=++id;
    			val[id]=v[i];
    		}
    		v[i]=mp[v[i]];
    		vec[v[i]].push_back(i);
    	}
    	for (int i=1; i<=n; i++)
    		belong[i]=(i-1)/block+1;
    	int cnt=(n-1)/block+1;
    	for (int i=1; i<=cnt; i++) pre(i);
    	for (int i=1; i<=m; i++){
    		int l,r;
    		scanf("%d%d",&l,&r);
    		l=(l+ans-1)%n+1,r=(r+ans-1)%n+1;
    		if (l>r) swap(l,r);
    		ans=val[calc(l,r)];
    		printf("%d
    ",ans);
    	}
    	return 0;
    }
    

      

  • 相关阅读:
    HttpModule和在Global.asax区别
    SQL Server中视图的特点与优化
    SQL中int类型与varchar类型的隐式转换
    利用SQL语句查询SQL中所有正在执行的命令
    jquery子窗体操作父窗体中的元素
    js 连接数据库
    典型的列变行,用动态语句来做
    js中with、this的用法
    SQL SERVER数据库状态(脱机,联机,可疑)及SQL设置语句详解
    UVA 10465 Homer Simpson
  • 原文地址:https://www.cnblogs.com/silenty/p/8877330.html
Copyright © 2020-2023  润新知