ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

【题解】 CF765F Souvenirs 分块

2020-12-28 21:37:05  阅读:242  来源: 互联网

标签:le end val int 题解 Souvenirs bl CF765F las


Legend

\(\textrm{Link to}\) Codeforces

给定长 \(n\ (2 \le n \le 10^5)\) 的序列 \(a\ (0 \le a_i \le 10^5)\),共 \(m\ (1 \le m \le 3\times 10^5)\) 次询问,每次询问一个区间 \([l,r]\) 最接近两数字之差。

Editorial

容易想到分块。

设 \(pre_{i,j}\) 表示 \(j\) 号位置到 \(i\) 号块起始位置的询问答案,\(suf_{i,j}\) 表示 \(j\) 号位置到 \(i\) 号块末尾位置的询问答案。

预处理可以使用链表进行 \(O(1)\) 查询前后缀。

考虑查询:

散块与整块的贡献直接通过 \(pre,suf\) 得到,散块之间的通过归并排序得到。

容易发现复杂度为 \(O(\dfrac{n}{B} B \log B + \dfrac{n^2}{B} + mB)\),当 \(B=\dfrac{n}{\sqrt{m}}\) 时取到最优 \(O(n\sqrt{m})\)

容易发现分块可以做到强制在线。

Code

#include <bits/stdc++.h>

#define debug(...) fprintf(stderr ,__VA_ARGS__)
#define __FILE(x)\
	freopen(#x".in" ,"r" ,stdin);\
	freopen(#x".out" ,"w" ,stdout)
#define LL long long

using namespace std;

const int MX = 1e5 + 23;
const LL MOD = 998244353;
const int SZ = 333;
const int NUM = MX / SZ + 1;

int read(){
	char k = getchar(); int x = 0;
	while(k < '0' || k > '9') k = getchar();
	while(k >= '0' && k <= '9') x = x * 10 + k - '0' ,k = getchar();
	return x;
}

void chkmin(int &a ,int b){a = std::min(a ,b);}

int a[MX] ,bl[MX] ,n ,m;

int begin(int x){return (x - 1) * SZ + 1;}
int end(int x){return std::min(begin(x + 1) - 1 ,n);}

int pre[SZ][MX] ,suf[SZ][MX];

int L[MX] ,R[MX] ,b[MX];

struct POINT{
	int val ,id;
	bool operator <(const POINT& B)const{
		return val == B.val ? id < B.id : val < B.val;
	}
}P[MX] ,Q[MX];

void init(){
	memset(pre ,0x3f ,sizeof pre);
	memset(suf ,0x3f ,sizeof suf);
	for(int i = 1 ; i <= n ; ++i){
		bl[i] = (i - 1) / SZ + 1;
		Q[i] = P[i] = (POINT){a[i] ,i};
	}
	for(int i = 1 ; begin(i) <= n ; ++i){
		std::sort(Q + begin(i) ,Q + 1 + end(i));
	}
	std::sort(P + 1 ,P + 1 + n);
	for(int i = 1 ; begin(i) <= n ; ++i){
		for(int j = 1 ,las = 0 ; j <= n ; ++j){
			R[P[j].id] = L[P[j].id] = 0;
			if(P[j].id < begin(i)) continue;
			if(las) R[las] = P[j].id;
			L[P[j].id] = las;
			las = P[j].id;
		}
		for(int j = n ; j >= begin(i) ; --j){
			int mx = INT_MAX;
			if(R[j]) chkmin(mx ,a[R[j]] - a[j]) ,L[R[j]] = L[j];
			if(L[j]) chkmin(mx ,a[j] - a[L[j]]) ,R[L[j]] = R[j];
			
			b[j] = mx;
		}
		for(int j = begin(i) ; j <= n ; ++j){
			pre[i][j] = std::min(pre[i][j - 1] ,b[j]);
		}
	}
	for(int i = bl[n] ; i ; --i){
		for(int j = 1 ,las = 0 ; j <= n ; ++j){
			R[P[j].id] = L[P[j].id] = 0;
			if(P[j].id > end(i)) continue;
			if(las) R[las] = P[j].id;
			L[P[j].id] = las;
			las = P[j].id;
		}
		for(int j = 1 ; j <= n ; ++j){
			int mx = INT_MAX;
			if(R[j]) chkmin(mx ,a[R[j]] - a[j]) ,L[R[j]] = L[j];
			if(L[j]) chkmin(mx ,a[j] - a[L[j]]) ,R[L[j]] = R[j];
			b[j] = mx;
		}
		for(int j = end(i) ; j ; --j){
			suf[i][j] = std::min(suf[i][j + 1] ,b[j]);
		}
	}
}

int query(int l ,int r){
	int ans = INT_MAX ,las = -1e9;
	if(bl[l] == bl[r]){
		for(int j = begin(bl[l]) ; j <= end(bl[l]) ; ++j){
			if(Q[j].id < l || Q[j].id > r) continue;
			chkmin(ans ,Q[j].val - las);
			las = Q[j].val;
		}
		return ans;
	}
	ans = std::min(pre[bl[l] + 1][r] ,suf[bl[r] - 1][l]);
	int p = begin(bl[l]) ,q = begin(bl[r]);
	while(p != end(bl[l]) + 1 || q != end(bl[r]) + 1){
		if(q == end(bl[r]) + 1 || (p != end(bl[l]) + 1 && Q[p].val <= Q[q].val)){
			if(Q[p].id >= l){
				chkmin(ans ,Q[p].val - las);
				las = Q[p].val;
			}
			++p;
		}
		else{
			if(Q[q].id <= r){
				chkmin(ans ,Q[q].val - las);
				las = Q[q].val;
			}
			++q;
		}
	}
	return ans;
}

int main(){
	n = read();
	for(int i = 1 ; i <= n ; ++i) a[i] = read();
	
	init();

	m = read();
	for(int i = 1 ,l ,r ; i <= m ; ++i){
		l = read() ,r = read();
		printf("%d\n" ,query(l ,r));
	}
	
	return 0;
}

标签:le,end,val,int,题解,Souvenirs,bl,CF765F,las
来源: https://www.cnblogs.com/imakf/p/14203727.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有