博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
CodeChef - QCHEF 分块
阅读量:7090 次
发布时间:2019-06-28

本文共 2834 字,大约阅读时间需要 9 分钟。

 

题目链接:http://vjudge.net/problem/174774/origin

题意:给定一个长度为n的序列a[],序列的值不大于m,现在有k个询问,每个询问给定(l,r).让你求出max{|x − y| : Li ≤ x, y ≤ Ri and Ax = Ay}。即区间[L,R]中值相同时,位置差的最大值

思路:分块,因为不带修改,所以我们就可以做预处理。求出last,first,Ans。 last[i][j]:值i在第j块最后出现的位置。first[i][j]:值i在第j块最早出现的位置。Ans[i][j]:第i块到第j块的值相同的最大位置差。

#define _CRT_SECURE_NO_DEPRECATE#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
using namespace std;typedef long long int LL;const int MAXN = 100000 + 10;int belong[MAXN], block, num, L[MAXN], R[MAXN];int n, m, q;int a[MAXN], last[MAXN][500], first[MAXN][500], Ans[500][500];int tim[MAXN], times, Pos[MAXN];int cal(int st, int ed){ int ans = 0; for (int i = L[st]; i <= R[st]; i++){ ans = max(ans, last[a[i]][ed] - i); } return ans;}void build(){ block = (int)sqrt(n + 0.5); num = n / block; if (n%block){ num++; } for (int i = 1; i <= num; i++){ L[i] = (i - 1)*block + 1; R[i] = i*block; } R[num] = n; for (int i = 1; i <= n; i++){ belong[i] = ((i - 1) / block) + 1; } memset(last, 0, sizeof(last)); memset(first, 0, sizeof(first)); memset(Ans, 0, sizeof(Ans)); times = 0; for (int i = 1; i <= n; i++){ last[a[i]][belong[i]] = i; } for (int i = n; i>0; i--){ first[a[i]][belong[i]] = i; } for (int i = 1; i <= m; i++){ for (int j = 1; j <= num; j++){ if (!last[i][j]){ last[i][j] = last[i][j - 1]; } } for (int j = num; j; j--){ if (!first[i][j]){ first[i][j] = first[i][j + 1]; } } } for (int i = num; i; i--){ for (int j = i; j <= num; j++){ Ans[i][j] = max(max(Ans[i + 1][j], Ans[i][j - 1]), cal(i, j)); } }}int query(int st, int ed){ int ans = 0; times++; if (belong[st] == belong[ed]){ for (int i = st; i <= ed; i++){ if (tim[a[i]] != times){ Pos[a[i]] = i; tim[a[i]] = times; } else{ ans = max(ans, i - Pos[a[i]]); } } return ans; } for (int i = st; i <= R[belong[st]]; i++){ if (tim[a[i]] != times){ Pos[a[i]] = i; tim[a[i]] = times; } else{ ans = max(ans, i - Pos[a[i]]); } ans = max(ans, last[a[i]][belong[ed] - 1] - i); } ans = max(ans, Ans[belong[st] + 1][belong[ed] - 1]); for (int i = L[belong[ed]]; i <= ed; i++){ if (tim[a[i]] != times){ Pos[a[i]] = i; tim[a[i]] = times; } else{ ans = max(ans, i - Pos[a[i]]); } ans = max(ans, i - first[a[i]][belong[st] + 1]); } return ans;}int main(){ //#ifdef kirito // freopen("in.txt", "r", stdin); // freopen("out.txt", "w", stdout); //#endif // int start = clock(); while (~scanf("%d%d%d", &n, &m, &q)){ for (int i = 1; i <= n; i++){ scanf("%d", &a[i]); } build(); int st, ed; for (int i = 1; i <= q; i++){ scanf("%d%d", &st, &ed); printf("%d\n", query(st, ed)); } } //#ifdef LOCAL_TIME // cout << "[Finished in " << clock() - start << " ms]" << endl; //#endif return 0;}

 

转载于:https://www.cnblogs.com/kirito520/p/5952353.html

你可能感兴趣的文章
iOS:提示框(警告框)控件UIActionSheet的详解
查看>>
分析Linux内核创建一个新进程的过程【转】
查看>>
Web API应用架构设计分析(2)
查看>>
.NET插件系统之二——不实例化获取插件信息和可视化方法
查看>>
让asp.net默认的上传组件支持进度条反映
查看>>
EXTJS学习系列提高篇:第十一篇(转载)作者殷良胜,制作树形菜单之五
查看>>
从代码分析Android-Universal-Image-Loader的图片加载、显示流程
查看>>
阿里妈妈首次公开新一代自研智能检索模型 | WWW 2018论文解读
查看>>
使用Depth Texture
查看>>
第 9 章 PBX
查看>>
ylbtech-LanguageSamples-Porperties(属性)
查看>>
第 4 章 Music score
查看>>
架构设计目录
查看>>
Wind7外接显示器选择拓展模式后,鼠标只能往右移动才能切换到外接显示器上,不能修改切换方向...
查看>>
学习笔记: CSS3 鼠标悬停动画
查看>>
ylbtech-cnblogs(博客园)-数据库设计-7,News(新闻)
查看>>
WCF 基础简介
查看>>
用Soap消息调用Web Services(续)
查看>>
php数据库操作封装类
查看>>
atitit.导出excel的设计----查询结果 导出为excel的实现java .net php 总结
查看>>