分块

这个以后再写吧。。。

写了一道bzoj2724, 蒲公英, 调不出来了, 先放下, 先继续复习NOIP的知识了

#include <iostream>
#include <cstdio>
#include <cmath>
#include <algorithm>
#include <cstring>
#define MAXN 40005
#define MAXM 36
using namespace std;
int n, m, b[MAXN], belong[MAXN], C[MAXM][MAXN], hash[MAXN], fim[MAXN];
struct point2
{
	int c[MAXN], maxx, pos;
}f[MAXM][MAXM];
struct point{
	int x, num;
}a[MAXN];
bool cmp(point a, point b){return a.x < b.x;}
inline int input(){
	int ret = 0;
	char c; c = getchar();
	while(c < '0' || c > '9')c = getchar();
	while(c >= '0' && c <= '9'){
		ret *= 10; ret += c - '0'; c = getchar();
	}return ret;
}
inline void update(int t, int v, int &Max, int &pos){
	if(v == Max && t < pos)pos = t;
	if(v > Max)pos = t, Max = v;
}
int cal(int l, int r){
	int L = belong[l], R = belong[r];
	if(L == R){
		int maxx = 0, pos = 0;
		for(int i = l; i <= r; i ++){
			hash[b[i]] ++;
			update(b[i], hash[b[i]], maxx, pos);
		}
		for(int i = l; i <= r; i ++) hash[b[i]] --;
		return a[pos].x;
	}
	else{
		if(belong[l] == belong[l - 1])L ++;
		if(belong[r] == belong[r + 1])R --;
		int poss = f[L][R].pos, maxxn = f[L][R].maxx;
		for(int i = l; belong[i] == belong[i - 1]; i ++) f[L][R].c[b[i]] ++, update(b[i], f[L][R].c[b[i]], f[L][R].maxx, f[L][R].pos);
		for(int i = r; belong[i] == belong[i + 1]; i --) f[L][R].c[b[i]] ++, update(b[i], f[L][R].c[b[i]], f[L][R].maxx, f[L][R].pos);
		int ret = a[f[L][R].pos].x;
		for(int i = l; belong[i] == belong[i - 1]; i ++) f[L][R].c[b[i]] --;
		for(int i = r; belong[i] == belong[i + 1]; i --) f[L][R].c[b[i]] --;
		f[L][R].pos = poss, f[L][R].maxx = maxxn;
		return ret;
	}
}
int main()
{
//	freopen("2724a.in", "r", stdin);
    n = input(); m = input();
    for(int i = 1; i <= n; i ++)a[i].x = input(), a[i].num = i;
    sort(a + 1, a + n + 1, cmp);
	a[0].x = 0;
	int cnt = 0;
	for(int i = 1; i <= n; i ++){
		if(a[i].x > a[i - 1].x)cnt ++;
		b[a[i].num] = cnt;
	}
	for(int i = 1; i <= n; i ++)printf("%d ", b[i]);
	int p = pow(n, 0.66666666666);
	int t = n / p; if(n % p)t ++;
	for(int i = 1; i <= n; i ++){
		if((i - 1) % p == 0)belong[i] = belong[i - 1] + 1;
		else belong[i] = belong[i - 1];
		C[belong[i]][b[i]] ++;
	}
	for(int i = 1; i <= t; i ++){
		for(int j = i; j <= t; j ++){
			for(int k = 1; k <= cnt; k ++)
				f[i][j].c[k] = f[i][j - 1].c[k] + C[j][k];
			for(int k = 1; k <= cnt; k ++)
				update(k, f[i][j].c[k], f[i][j].maxx, f[i][j].pos);
		}
	}
	int x = 0;
	for(int i = 1; i <= m; i ++){
		int l = input(), r = input();
		l = (l + x - 1) % n + 1; r = (r + x - 1) % n + 1;
		if(l > r)swap(l, r);
		printf("%d\n", x = cal(l, r));
	}
    system("pause");
    return 0;    
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值