BZOJ2724. [Violet 6]蒲公英(分块)

版权声明:转载请声明出处,谢谢支持 https://blog.csdn.net/Dreamstar_DS/article/details/83215853

DAY - 20
——远方的冲锋号角音游天际
题目链接:https://www.lydsy.com/JudgeOnline/problem.php?id=2724
OR https://darkbzoj.cf/problem/2724

8个小时的斗智斗勇…
我也不知道为什么这道题成了我目前所有学科中用时最长的一道题
听说此题可以各种暴力卡过233
其实就是一个很简单的预处理,由于分块思想(即只暴力处理角块)我们就可以预处理出整块之间的众数(nsqrt(n)),然后对于每个区间我们就需要处理角块即可~(暴力取最优)
本题需要一个简单的离散化(甚至你不需要排序)
本题块大小取sqrt(n / log2(n))最优(我也不知道为什么,当然你sqrt(n)也是可以过的)
AC Code:

#include<bits/stdc++.h>
#define rg register
#define maxn 200005
#define il inline
#define ll long long
using namespace std;
il int read(){rg int x = 0  , w = 1;rg char ch = getchar();while (ch < '0' || ch > '9') {if (ch == '-') w = -1;ch = getchar();}while (ch >= '0' && ch <= '9'){x = (x<<3) + (x<<1) + ch - '0';ch = getchar();}return x * w;}
int a[maxn] , b[maxn] , belong[maxn] , sum[maxn];
int num , sum2[maxn] , tot , q[maxn] , cnt[50002] , f[1000][1000];
int totn , val[maxn] , block;
vector <int> v[50005];
map<int , int>mp;
void init(int n){
	block = sqrt(n / log2(n));
	for (rg int i = 1 ; i <= n ; ++i)
		belong[i] = (i - 1) / block + 1;
}
void pre(int n){
	for (rg int i = 1 ; i <= belong[n] ; ++i){
		memset(cnt , 0 , sizeof(cnt));
		rg int ans = 0 , mx = 0;
		for (rg int j = (i - 1) * block + 1; j <= n ; ++j){
			++cnt[a[j]];
			if (cnt[a[j]] > mx || (cnt[a[j]] == mx && val[a[j]] < val[ans]))
				ans = a[j] , mx = cnt[a[j]];
			f[i][belong[j]] = ans;
		}
	}
}
int find(int l0 , int r0 , int x){
	rg int t = upper_bound(v[x].begin() , v[x].end() , r0) - lower_bound(v[x].begin() , v[x].end() , l0);	
	return t;
}
int query(int l0 , int r0){
	rg int ans = f[belong[l0] + 1][belong[r0] - 1] , mx = find(l0 , r0 , ans);
	rg int tmp;
	rg int minr = min(r0 , belong[l0] * block);
	for (rg int i = l0 ; i <= minr ; ++i){
		tmp = find(l0 , r0 , a[i]);
		if (tmp > mx || (tmp == mx && val[a[i]] < val[ans]))
			mx = tmp , ans = a[i];
	}
	if (belong[l0] != belong[r0])
		for (rg int i = (belong[r0] - 1) * block + 1 ; i <= r0 ; ++i){
			tmp = find(l0 , r0 , a[i]);
			if (tmp > mx || (tmp == mx && val[a[i]] < val[ans]))
				mx = tmp , ans = a[i];	
		}
	return ans;
}
int main(){
	rg int n = read() , m = read() , x , c;
	for (rg int i = 1 ; i <= n ; ++i){
		a[i] = b[i] = read();
	}
	sort(b + 1 , b + 1 + n);
	tot = unique(b + 1 , b + 1 + n) - (b + 1);
	for (rg int i = 1 ; i <= n ; ++i){
		rg int x = a[i];
		a[i] = lower_bound(b + 1 , b + 1 + n , x) - b;
		val[a[i]] = x;
		v[a[i]].push_back(i);
	}
	init(n);
	pre(n);
	int l0 , r0 , ans = 0;
	memset(sum , 0 , sizeof(sum));
	for (rg int i = 1 ; i <= m ; ++i){
		l0 = (read() + ans - 1) % n + 1 , r0 = (read() + ans - 1) % n + 1;
		if (l0 > r0)
			swap(l0 , r0);
		printf("%d\n" , ans = val[query(l0 , r0)]);
	}
	return 0;	
}

猜你喜欢

转载自blog.csdn.net/Dreamstar_DS/article/details/83215853