[BZOJ2724][Violet 6]蒲公英

试题描述

输入

修正一下

l = (l_0 + x - 1) mod n + 1, r = (r_0 + x - 1) mod n + 1

输出

输入示例


输出示例


数据规模及约定

修正下:

n <= 40000, m <= 50000

题解

分块,先预处理出 f[i][j] 表示第 i 块到第 j 块的众数,枚举起点 i 然后扫一遍就好了。

其次是询问,对于一个询问 [ql, qr],其中 ql 属于块 l,qr 属于块 r,众数要么是 f[l+1][r-1],要么是不完整块中的数,所以我们需要搞一个 calc(l, r, x) 功能,表示询问 [l, r] 中 x 出现的次数,有了这个功能后就可以做到把答案初始设为 f[l+1][r-1](O(1)),然后 O(sqrt(n)) 暴力枚举不完整块中的数,如果出现次数比当前的多,就更新答案。

这个 calc() 函数可以这样搞:把所有数离散,每个数的位置记下来,然后当询问 calc(l, r, x) 在 x 的位置序列上二分一下就可以计算了。

#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <algorithm>
#include <cmath>
#include <vector>
using namespace std; const int BufferSize = 1 << 16;
char buffer[BufferSize], *Head, *Tail;
inline char Getchar() {
if(Head == Tail) {
int l = fread(buffer, 1, BufferSize, stdin);
Tail = (Head = buffer) + l;
}
return *Head++;
}
int read() {
int x = 0, f = 1; char c = Getchar();
while(!isdigit(c)){ if(c == '-') f = -1; c = Getchar(); }
while(isdigit(c)){ x = x * 10 + c - '0'; c = Getchar(); }
return x * f;
} #define maxn 40010
#define maxq 210
int n, m, num[maxn], A[maxn], st[maxq], en[maxq], bl[maxn], cntb, f[maxq][maxq], cntn[maxn]; vector <int> pos[maxn];
int calc(int l, int r, int x) {
return upper_bound(pos[x].begin(), pos[x].end(), r) - lower_bound(pos[x].begin(), pos[x].end(), l);
}
int query(int ql, int qr) {
int l = bl[ql], r = bl[qr];
if(r - l <= 1) {
int ans = A[ql], mx = calc(ql, qr, ans);
for(int i = ql + 1; i <= qr; i++) {
int tmp = calc(ql, qr, A[i]);
if(mx < tmp || (mx == tmp && ans > A[i])) ans = A[i], mx = tmp;
}
return ans;
}
int ans = f[l+1][r-1], mx = calc(ql, qr, ans);
for(int i = ql; i <= en[l]; i++) {
int tmp = calc(ql, qr, A[i]);
if(mx < tmp || (mx == tmp && ans > A[i])) ans = A[i], mx = tmp;
}
for(int i = st[r]; i <= qr; i++) {
int tmp = calc(ql, qr, A[i]);
if(mx < tmp || (mx == tmp && ans > A[i])) ans = A[i], mx = tmp;
}
return ans;
} int main() {
n = read(); m = read();
int siz = (int)sqrt(n + .5);
for(int i = 1; i <= n; i++) {
num[i] = A[i] = read();
int p = (i - 1) / siz + 1; cntb = p;
if(!st[p]) st[p] = i;
en[p] = i;
bl[i] = p;
} sort(num + 1, num + n + 1);
for(int i = 1; i <= n; i++) A[i] = lower_bound(num + 1, num + n + 1, A[i]) - num;
for(int i = 1; i <= cntb; i++) {
memset(cntn, 0, sizeof(cntn));
for(int j = st[i]; j <= n; j++) {
cntn[A[j]]++;
int r = bl[j];
if(r > i && !f[i][r]) f[i][r] = f[i][r-1];
if(!f[i][r] || cntn[f[i][r]] < cntn[A[j]] || (cntn[f[i][r]] == cntn[A[j]] && f[i][r] > A[j]))
f[i][r] = A[j];
}
}
for(int i = 1; i <= n; i++) pos[A[i]].push_back(i); int x = 0;
while(m--) {
int l = (read() + x - 1) % n + 1, r = (read() + x - 1) % n + 1;
if(l > r) swap(l, r);
int tmp = query(l, r);
printf("%d\n", num[tmp]);
x = num[tmp];
} return 0;
}

[BZOJ2724][Violet 6]蒲公英的更多相关文章

  1. BZOJ2724 [Violet 6]蒲公英 分块

    原文链接https://www.cnblogs.com/zhouzhendong/p/BZOJ2724.html 题目传送门 - BZOJ2724 题意 求区间最小众数,强制在线. $n$ 个数,$m ...

  2. bzoj2724: [Violet 6]蒲公英(离散化+分块)

    我好弱啊..这题调了2天QwQ 题目大意:给定一个长度为n(n<=40000)的序列,m(m<=50000)次询问l~r之间出现次数最多的数.(区间众数) 这题如果用主席树就可以不用处理一 ...

  3. bzoj2724: [Violet 6]蒲公英 分块 区间众数 论algorithm与vector的正确打开方式

    这个,要处理各个数的话得先离散,我用的桶. 我们先把每个块里的和每个块区间的众数找出来,那么在查询的时候,可能成为[l,r]区间的众数的数只有中间区间的众数和两边的数. 证明:若不是这里的数连区间的众 ...

  4. 【分块】bzoj2724 [Violet 6]蒲公英

    分块,离散化,预处理出: ①前i块中x出现的次数(差分): ②第i块到第j块中的众数是谁,出现了多少次. 询问的时候,对于整块的部分直接获得答案:对于零散的部分,暴力统计每个数出现的次数,加上差分的结 ...

  5. bzoj2724: [Violet 6]蒲公英(分块)

    传送门 md调了一个晚上最后发现竟然是空间开小了……明明算出来够的…… 讲真其实我以前不太瞧得起分块,觉得这种基于暴力的数据结构一点美感都没有.然而今天做了这道分块的题才发现分块的暴力之美(如果我空间 ...

  6. 【BZOJ2724】[Violet 6]蒲公英 分块+二分

    [BZOJ2724][Violet 6]蒲公英 Description Input 修正一下 l = (l_0 + x - 1) mod n + 1, r = (r_0 + x - 1) mod n ...

  7. BZOJ 2724: [Violet 6]蒲公英

    2724: [Violet 6]蒲公英 Time Limit: 40 Sec  Memory Limit: 512 MBSubmit: 1633  Solved: 563[Submit][Status ...

  8. BZOJ 2724: [Violet 6]蒲公英( 分块 )

    虽然AC了但是时间惨不忍睹...不科学....怎么会那么慢呢... 无修改的区间众数..分块, 预处理出Mode[i][j]表示第i块到第j块的众数, sum[i][j]表示前i块j出现次数(前缀和, ...

  9. BZOJ_2724_[Violet 6]蒲公英_分块

    BZOJ_2724_[Violet 6]蒲公英_分块 Description Input 修正一下 l = (l_0 + x - 1) mod n + 1, r = (r_0 + x - 1) mod ...

随机推荐

  1. [wikioi 1307][poj 2054]欧少堆(乱搞)

    题目:http://www.wikioi.com/problem/1307/ 题意:给你一个树,上面有n个节点,每个节点都有一个价值p,求一个n个节点的排列顺序,是的Σi*p[i]最小(要求父节点一定 ...

  2. 08.C# System.Nulable<T>和空引用操作符(四章4.2-4.4)

    看了这3小节,发现作者讲得太详细了,把一个都在正常使用的用法说得太神密了,搞得不知是自己不懂作者的苦心,还是作者用意为之,这里给大家都简单讲下吧,太深的真心讲不下去. 1.可空类型的核心部分是Syst ...

  3. 每天一个linux命令(20):linux chmod命令

    chmod命令用于改变linux系统文件或目录的访问权限.用它控制文件或目录的访问权限.该命令有两种用法.一种是包含字母和操作符表达式的文字设定法:另一种是包含数字的数字设定法. Linux系统中的每 ...

  4. Git 常用命令详解(二)

    Git 是一个很强大的分布式版本管理工具,它不但适用于管理大型开源软件的源代码(如:linux kernel),管理私人的文档和源代码也有很多优势(如:wsi-lgame-pro) Git 的更多介绍 ...

  5. 问问题_为什么关闭浏览器后Session会失效

    首先需要理解一下几点: 1.Http是无状态的,即对于每一次请求都是一个全新的请求,服务器不保存上一次请求的信息 2.Session是保存在服务端的,为什么后续请求会读取到session?因为请求会包 ...

  6. 【codevs 1296】营业额统计 水~~

    今天下午先写一个Splay水题来复习一下Splay模板.是不是有点太水了做这种水题我有点良心不安. 可笑的是一开始我竟然WA了一组,看来是我低估水题的数据范围了,我是空节点直接返回inf或-inf,明 ...

  7. hdu3613 扩展KMP

    #include<stdio.h> #include<string.h> #define maxn 501000 char s[maxn],t[maxn]; int next[ ...

  8. Matlab最短路径问题记录

    利用graphshortestpath 可以求最短路径,具体用法参考MATLAB帮助 S=[1 1 2 2 3 3 4 4 4 4 5 6 6 7 8]; %起始节点向量 E=[2 3 5 4 4 6 ...

  9. 【codevs1409】 拦截导弹 2

    http://codevs.cn/problem/1409/ (题目链接) 题意 给出n个三维的导弹,每次拦截只能打x,y,z严格上升的若干个导弹,求最多能一次拦截下多少个导弹,以及最少拦截几次将所有 ...

  10. poj3207 2-SAT入门

    一开始题意没读懂 = = 题意:比如说对于表盘上a到b.c到d都要连边,这两个边不能交叉.这两个边要么都在圆内要么都在圆外,而且可以是曲线= = 比如这种情况:(Reference:http://bl ...