博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
[洛谷P4168][Violet]蒲公英
阅读量:7002 次
发布时间:2019-06-27

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

题目大意:有$n(n\leqslant4\times10^4)$个数,$m(m\leqslant5\times10^4)$个询问,每次问区间$[l,r]$内的众数,若相同输出最小的,强制在线。

题解:先离散化,分块,设块大小为$S$,可以在$O(\dfrac n S n)$的复杂度内预处理出每两个块间的众数。考虑询问,发现询问中的众数要么是整块的那一个众数,要么就是非整块内出现过的数,可以用主席树查询区间数出现个数,比较一下即可,一次查询复杂度$O(2S\log_2 n)$。$S$开的比$\sqrt n$小一点就行了

卡点:主席树查询时左端点没有减一,数组开小

 

C++ Code:

#include 
#include
#include
#include
namespace __IO { namespace R { int x, ch; inline int read() { while (isspace(ch = getchar())); for (x = ch & 15; isdigit(ch = getchar());) x = x * 10 + (ch & 15); return x; } }}using __IO::R::read;#define maxn 40010const int BSZ = 100, Bnum = maxn / BSZ + 5;namespace SgT {#define N (maxn * 20) int lc[N], rc[N], V[N], idx; void insert(int &rt, const int l, const int r, const int num) { lc[++idx] = lc[rt], rc[idx] = rc[rt], V[idx] = V[rt] + 1, rt = idx; if (l == r) return ; const int mid = l + r >> 1; if (num <= mid) insert(lc[rt], l, mid, num); else insert(rc[rt], mid + 1, r, num); } int query(const int L, const int R, const int l, const int r, const int num) { if (l == r) return V[R] - V[L]; const int mid = l + r >> 1; if (num <= mid) return query(lc[L], lc[R], l, mid, num); else return query(rc[L], rc[R], mid + 1, r, num); }#undef N}int n, m, ans, anscnt;int rt[maxn];int v[maxn], s[maxn], bl[maxn];int L[Bnum], R[Bnum], cnt[maxn];int Max[Bnum][Bnum];int main() { n = read(), m = read(); for (int i = 1; i <= n; i++) { v[i] = s[i] = read(); bl[i] = i / BSZ + 1; } int tot = (std::sort(v + 1, v + n + 1), std::unique(v + 1, v + n + 1) - v - 1); for (int i = 1; i <= n; i++) { SgT::insert(rt[i] = rt[i - 1], 1, tot, s[i] = std::lower_bound(v + 1, v + tot + 1, s[i]) - v); } const int B = bl[n]; for (int i = 1; i <= B; i++) L[i] = (i - 1) * BSZ, R[i] = L[i] + BSZ - 1; L[1] = 1, R[B] = n; for (int l = 1, r, M; l <= B; l++) { r = l, M = 0; memset(cnt, 0, sizeof cnt); for (int i = L[l]; i <= n; i++) { cnt[s[i]]++; if (cnt[s[i]] > cnt[M] || (cnt[s[i]] == cnt[M] && s[i] < M)) M = s[i]; if (i == R[r]) Max[l][r] = M, r++; } } while (m --> 0) { int l = (read() + ans - 1) % n + 1, r = (read() + ans - 1) % n + 1; if (l > r) std::swap(l, r); const int lb = bl[l], rb = bl[r]; ans = anscnt = 0;#define check(x) {\ const int tmp = SgT::query(rt[l - 1], rt[r], 1, tot, x); \ if (tmp > anscnt || (tmp == anscnt && x < ans)) ans = x, anscnt = tmp;\} if (lb == rb) { for (register int i = l; i <= r; i++) check(s[i]); } else { for (register int i = l; i <= R[lb]; i++) check(s[i]); if (lb + 1 <= rb - 1) check(Max[lb + 1][rb - 1]); for (register int i = L[rb]; i <= r; i++) check(s[i]); }#undef check printf("%d\n", ans = v[ans]); } return 0;}

  

转载于:https://www.cnblogs.com/Memory-of-winter/p/10086535.html

你可能感兴趣的文章
处在LV1太长了··
查看>>
软件工程综合实践阶段小结
查看>>
人工神经网络简介
查看>>
改善我们的神经网络
查看>>
文件操作的其他模式
查看>>
链表与顺序表的对比
查看>>
windows phone 8 新增功能:从一个应用程序启动另一个程序(file association 和 Protocol association两种方式)...
查看>>
Angularjs总结(七) 路由及请求服务等
查看>>
Bindservice开启服务特点
查看>>
centos session
查看>>
Google Code Jam 2014 资格赛:Problem D. Deceitful War
查看>>
上传文件
查看>>
串口波形分析
查看>>
html5-css列表和表格
查看>>
【Web自动化测试——代码篇十二】自动化测试模型——数据驱动测试和关键字驱动测试...
查看>>
.net判断System.Data.DataRow中是否包含某列
查看>>
Design T-Shirt 排序
查看>>
javaweb项目中关于配置文件web.xml的解析
查看>>
循环语句
查看>>
noip rp++
查看>>