【洛谷 P4168】[Violet]蒲公英(分块)
题目链接
题目大意:给定\(n\)个数和\(m\)个求区间众数的询问,强制在线
这题我\(debug\)了整整一个下午啊。。-_- 从14:30~16:45终于\(debug\)出来了,\(debug\)的难度主要就在\(Luogu\)数据不能下载,然后\(Contest Hunter\)的数据又太大了(最小的\(n=500,m=1000\)),只能人工查错,一行行检查代码,哎。。。写不出正解还是算了吧,考试时可没有这么多时间\(debug\)。
做法:先离散化,然后分块,每块大小\(\sqrt n\),预处理任意两块之间的众数,每个编号前\(k\)块出现的次数,也就是前缀和,我们就能很快求出任意两块之间\(k\)出现的次数了。
把要求的区间\([l,r]\)分成3个部分,左边不足一块的部分,右边不足一块的部分和中间的很多块,那么众数只可能出现在:
1,左边、右边不足一块的部分
2,中间很多块的众数
也就是说,中间很多块的不是众数又没在左右两部分出现过的,都不可能是\([l,r]\)的众数。
于是暴力扫一边左右两个部分,对于每个数\(i\),第一次扫到\(i\)的时候把计数器加上中间那些块里面\(i\)的出现次数,不断更新众数。
最后判断一下如果中间那些块的众数没在左右部分出现过,那么再用中间那些块的众数尝试更新答案。
Code:
(保留了debug)
#include <cstdio>
#include <cmath>
#include <algorithm>
#include <cstring>
#define re register
const int MAXN = 40010;
const int MAXSIZE = 800;
using namespace std;
inline int read(){
int s = 0, w = 1;
char ch = getchar();
while(ch < '0' || ch > '9') { if(ch == '-') w = -1; ch = getchar(); }
while(ch >= '0' && ch <= '9') { s = s * 10 + ch - '0'; ch = getchar(); }
return s * w;
}
struct point{
int id, val;
point(){ id = val = 0; }
bool operator < (const point A) const{
return val < A.val;
}
}s[MAXN];
int SIZE;
int common[MAXSIZE][MAXSIZE], belong[MAXN], a, b, pos[MAXN], p[MAXN][MAXSIZE], c[MAXN], d[MAXN], cnt, num, ans;
int n, m;
inline int get(int l, int r, int k){
return p[k][r] - p[k][l - 1];
}
int Solve(int l, int r){
if(l > r) swap(l, r);
int Com = 0, Max = 0;
if(belong[l] == belong[r]){
for(int i = l; i <= r; ++i)
if(++c[pos[i]] > Max || (c[pos[i]] == Max && pos[i] < Com)) Max = c[pos[i]], Com = pos[i];
for(int i = l; i <= r; ++i)
c[pos[i]] = 0;
}
else if(belong[r] - belong[l] == 1){
int e = belong[l] * SIZE;
for(int i = l; i <= e; ++i)
if(++c[pos[i]] > Max || (c[pos[i]] == Max && pos[i] < Com)) Max = c[pos[i]], Com = pos[i];
for(int i = (belong[r] - 1) * SIZE + 1; i <= r; ++i)
if(++c[pos[i]] > Max || (c[pos[i]] == Max && pos[i] < Com)) Max = c[pos[i]], Com = pos[i];
for(int i = l; i <= e; ++i)
c[pos[i]] = 0;
for(int i = (belong[r] - 1) * SIZE + 1; i <= r; ++i)
c[pos[i]] = 0;
}
else{
int e = belong[l] * SIZE;
for(int i = l; i <= e; ++i){
if(++c[pos[i]] == 1) c[pos[i]] += get(belong[l] + 1, belong[r] - 1, pos[i]);
if(c[pos[i]] > Max || (c[pos[i]] == Max && pos[i] < Com)) Max = c[pos[i]], Com = pos[i];
}
for(int i = (belong[r] - 1) * SIZE + 1; i <= r; ++i){
if(++c[pos[i]] == 1) c[pos[i]] += get(belong[l] + 1, belong[r] - 1, pos[i]);
if(c[pos[i]] > Max || (c[pos[i]] == Max && pos[i] < Com)) Max = c[pos[i]], Com = pos[i];
}
int L = belong[l] + 1; int R = belong[r] - 1;
if(!c[common[L][R]]){
c[common[L][R]] += get(L, R, common[L][R]);
if(c[common[L][R]] > Max || (c[common[L][R]] == Max && common[L][R] < Com)) Com = common[L][R];
c[common[L][R]] = 0;
}
for(int i = l; i <= e; ++i)
c[pos[i]] = 0;
for(int i = (belong[r] - 1) * SIZE + 1; i <= r; ++i)
c[pos[i]] = 0;
}
return d[Com];
}
int main(){
//freopen("xsxs.txt","r",stdin);
//freopen("xslb.txt","w",stdout);
scanf("%d%d", &n, &m);
SIZE = sqrt(n + 0.5); num = ceil((double)n / SIZE);
for(int i = 1; i <= n; ++i){
belong[i] = (i - 1) / SIZE + 1; //属于哪块
s[i].id = i;
scanf("%d", &s[i].val);
}
sort(s + 1, s + n + 1);
for(int i = 1; i <= n; ++i){ //离散化
if(s[i].val != s[i - 1].val)
pos[s[i].id] = ++cnt;
else pos[s[i].id] = cnt;
d[cnt] = s[i].val;
}
for(int i = 1; i <= n; ++i)
++p[pos[i]][belong[i]];
for(int i = 1; i <= n; ++i)
for(int j = 2; j <= num; ++j)
p[i][j] += p[i][j - 1]; //前缀和
for(int i = 1; i <= num; ++i){ //任意两块的众数
int Max = 0, cm = 0;
for(int j = i; j <= num; ++j){
for(int k = (j - 1) * SIZE + 1; k <= SIZE * j; ++k)
if(++c[pos[k]] > Max || (c[pos[k]] == Max && pos[k] < cm)) //出现次数最多且编号最小的为众数
Max = c[pos[k]], cm = pos[k];
common[i][j] = common[j][i] = cm;
}
memset(c, 0, sizeof c);
}
for(int i = 1; i <= m; ++i){
scanf("%d%d", &a, &b);
printf("%d\n", ans = Solve((a + ans - 1) % n + 1, (b + ans - 1) % n + 1));
}
/*int Max = 0;
for(int i = 60; i <= 362; ++i){
printf("%d ", d[pos[i]]);
if(d[pos[i]] == 39881273) printf("\n%d\n", pos[i]);
if(++c[pos[i]] > Max) Max = c[pos[i]];
}*/
//printf("\n%d", d[41]);
//fclose(stdin);
//fclose(stdout);
//system("pause");
return 0;
}
【洛谷 P4168】[Violet]蒲公英(分块)的更多相关文章
- 洛谷 P4168 [Violet]蒲公英 解题报告
P4168 [Violet]蒲公英 题目背景 亲爱的哥哥: 你在那个城市里面过得好吗? 我在家里面最近很开心呢.昨天晚上奶奶给我讲了那个叫「绝望」的大坏蛋的故事的说!它把人们的房子和田地搞坏,还有好多 ...
- [洛谷P4168][Violet]蒲公英
题目大意:有$n(n\leqslant4\times10^4)$个数,$m(m\leqslant5\times10^4)$个询问,每次问区间$[l,r]$内的众数,若相同输出最小的,强制在线. 题解: ...
- 洛谷 P4168 [Violet] 蒲公英
历尽千辛万苦终于AC了这道题目... 我们考虑1个区间\([l,r]\), 被其完整包含的块的区间为\([L,R]\) 那么众数的来源? 1.\([l,L)\)或\((R,r]\)中出现的数字 2.\ ...
- 「分块系列」「洛谷P4168 [Violet]」蒲公英 解题报告
蒲公英 Description 我们把所有的蒲公英看成一个长度为\(n\)的序列(\(a_1,a_2,...a_n\)),其中\(a_i\)为一个正整数,表示第i棵蒲公英的种类的编号. 每次询问一个区 ...
- Luogu P4168 [Violet]蒲公英 分块
这道题算是好好写了.写了三种方法. 有一个好像是$qwq$$N\sqrt(N)$的方法,,但是恳请大佬们帮我看看为什么这么慢$qwq$(后面的第三种) 注:$pos[i]$表示$i$属于第$pos[i ...
- 洛谷P1445 [Violet] 樱花 (数学)
洛谷P1445 [Violet] 樱花 题目背景 我很愤怒 题目描述 求方程 1/X+1/Y=1/(N!) 的正整数解的组数,其中N≤10^6. 解的组数,应模1e9+7. 输入输出格式 输入格式: ...
- 洛谷P4168 蒲公英 分块处理区间众数模板
题面. 许久以前我还不怎么去机房的时候,一位大佬好像一直在做这道题,他称这道题目为"大分块". 其实这道题目的思想不只可以用于处理区间众数,还可以处理很多区间数值相关问题. 让我们 ...
- 洛谷P4198 楼房重建 (分块)
洛谷P4198 楼房重建 题目描述 小A的楼房外有一大片施工工地,工地上有N栋待建的楼房.每天,这片工地上的房子拆了又建.建了又拆.他经常无聊地看着窗外发呆,数自己能够看到多少栋房子. 为了简化问题, ...
- 洛谷P4135 作诗 (分块)
洛谷P4135 作诗 题目描述 神犇SJY虐完HEOI之后给傻×LYD出了一题: SHY是T国的公主,平时的一大爱好是作诗. 由于时间紧迫,SHY作完诗之后还要虐OI,于是SHY找来一篇长度为N的文章 ...
- 洛谷P3247 [HNOI2016]最小公倍数 [分块,并查集]
洛谷 思路 显然,为了达到这个最小公倍数,只能走\(a,b\)不是很大的边. 即,当前询问的是\(A,B\),那么我们只能走\(a\leq A,b\leq B\)的边. 然而,为了达到这最小公倍数,又 ...
随机推荐
- es6严格模式需要注意的地方
1.块级函数 "use strict"; if (true) { function f() { } // 语法错误 } es5中严格模式下禁止声明块级函数,而在es6的严格模式中可 ...
- SVM知识点
SVM(Support Vector Machine),支持向量机,有监督学习模型,一种分类模型.在特征空间(输入空间为欧式空间或离散集合,特征空间为欧式空间或希尔伯特空间)中寻找间隔最大化的分离超平 ...
- FetchType.LAZY 时属性加上@JsonIgnore,避免返回时报错:Could not write JSON: failed to lazily initialize a collection of role
[示例] @OneToMany(fetch=FetchType.LAZY) @JsonIgnore @Fetch(FetchMode.SELECT) @Cascade(value={CascadeTy ...
- struts2中的action为什么要继承ActionSupport类,不继承也可以,有什么好处?
简单来说,有很多相关的方法都加载进来,你直接调用就行了,而且在安全上和稳定性上做了很好的处理 实际上继承ActionSupport之后 就等同于实现了很多接口 Action,Validateable, ...
- Week3 Teamework from Z.XML-团队分工及贡献分分配办法
引言:团队项目即将开展,本文将就团队分工,以及分数分配办法进行阐述 一.团队分工 本周我们团队进行了初步的分工,结果如下: PM: 李孟 Dev:毛宇 薛亚杰 肖俊鹏 罗凡 Test:周敏轩 马辰 李 ...
- IDEA无法新建GUI Form文件
因为最近想开发一个IDEA的插件,所以在开发的过程中就需要创建Swing GUI Form文件.但是在项目中右键New中始终就是没有“GUI Form”这个选项,然后自己琢磨寻思着是不是没有启用Swi ...
- 【Autofac】- 创建的类的生命周期
1.InstancePerDependency 对每一个依赖或每一次调用创建一个新的唯一的实例.这也是默认的创建实例的方式. 官方文档解释:Configure the component so tha ...
- php开发中处理emoji表情和颜文字的兼容问题
背景:随着手机的普及,现在移动开发很火爆,已经远远超过了pc端.在移动设备经常会发生用户发送的内容中包含emoji表情,在显示时就是乱码.一般是因为Mysql表设计时,都是用UTF8字符集的.把带有e ...
- 【bzoj3626】[LNOI2014]LCA 树链剖分+线段树
题目描述 给出一个n个节点的有根树(编号为0到n-1,根节点为0).一个点的深度定义为这个节点到根的距离+1.设dep[i]表示点i的深度,LCA(i,j)表示i与j的最近公共祖先.有q次询问,每次询 ...
- hdu 1267 下沙的沙子有几粒? (递推)
下沙的沙子有几粒? Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others)Total S ...