P4168 蒲公英 分块

把信息全部按块处理,在本题中体现的是块内众数(p[i])和块间次数(sum[i][j])
Remarks:
1.桶暴力
2.离散化
3.前缀和

#include<bits/stdc++.h>
#define ll long long
#define maxn 40003
#define inf 1e9+2
using namespace std;
int n, m, pp, num;
int a[maxn], b[maxn], L[220], R[220], pos[maxn], color[maxn], tong[maxn], ans[maxn];
int p[220][220], sum[220][maxn];

void init(int n) {
	int bz = sqrt(n * 1.0);
	num = n / bz;
	if (n % bz) num++;
	for (int i = 1; i <= num; ++i) L[i] = (i - 1) * bz + 1, R[i] = i * bz;
	R[num] = n;
	
	for (int i = 1; i <= num; ++i) {
		for (int j = L[i];  j <= R[i]; ++j) {
			pos[j] = i;
			sum[i][a[j]]++;
		}  
	}
	
	for (int i = 1; i <= num; ++i) {
		for (int j = 1; j <= pp; ++j) sum[i][j] += sum[i - 1][j];
	}
	
	
	for (int i = 1; i <= num; ++i) {
		int tot = 0, col = inf;
		for (int j = L[i]; j <= n; ++j) {
			tong[a[j]]++;
			if (tong[a[j]] > tot || (tong[a[j]] == tot && a[j] < col)) col = a[j], tot = tong[a[j]];
			p[i][pos[j]] = col;
		}
		for (int j = L[i]; j <= n; ++j) tong[a[j]]=0;
	}		
} 

int query(int l, int r) {
	memset(tong, 0, sizeof(tong));
	int p1 = pos[l], p2 = pos[r];
	int tot = 0, col = inf;
	if (p2 - p1 <= 1) {
		for (int j = l;  j <= r; ++j) {
			tong[a[j]]++;
			if (tong[a[j]] > tot || (tong[a[j]] == tot) && a[j] < col) tot = tong[a[j]], col = a[j];
			
		}
		return col;
	}
	
	int ans = p[p1 + 1][p2 - 1];
	tot = sum[p2 - 1][ans] - sum[p1][ans];
	int x = l, y = L[p1 + 1] - 1;
	for (int i = x; i <= y; ++i) {
		++tong[a[i]];
		if (tong[a[i]] + sum[p2 - 1][a[i]] - sum[p1][a[i]] > tot || (tong[a[i]] + sum[p2 - 1][a[i]] - sum[p1][a[i]] == tot && ans > a[i])) tot = tong[a[i]] + sum[p2 - 1][a[i]] - sum[p1][a[i]], ans = a[i];
	}
	
	x = L[p2], y = r;
	for (int i = x; i <= y; ++i) {
		++tong[a[i]];
		if (tong[a[i]] + sum[p2 - 1][a[i]] - sum[p1][a[i]] > tot || (tong[a[i]] + sum[p2 - 1][a[i]] - sum[p1][a[i]] == tot && ans > a[i])) tot = tong[a[i]] + sum[p2 - 1][a[i]] - sum[p1][a[i]], ans = a[i];
	}
	
	return ans;
}

int main() {
	cin>>n>>m;
	for (int i = 1; i <= n; ++i) cin>>a[i];
	for (int i = 1; i <= n; ++i) b[i] = a[i];
	
	sort(b + 1, b + n + 1);
	pp = unique(b + 1, b + n + 1) - b - 1;
	
	for (int i = 1; i <= n; ++i) {
		int col = a[i];
		a[i] = lower_bound(b + 1, b + 1 + pp, a[i]) - b;
		color[a[i]] = col;
	} 
	init(n);
	for (int i = 1; i <= m; ++i) {
		int l, r; cin>>l>>r;
		
		int x = (l + ans[i - 1] - 1) % n + 1;
		int y = (r + ans[i - 1] - 1) % n + 1;
		if (x > y) swap(x, y);
		ans[i] = color[query(x, y)];
		cout<<ans[i]<<endl;
	}
	return 0;
}
posted @ 2025-12-07 09:55  Wuyou2008  阅读(0)  评论(0)    收藏  举报