BZOJ_2724_[Violet 6]蒲公英_分块

Description

Input

修正一下

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

Output

Sample Input

6 3
1 2 3 2 1 2
1 5
3 6
1 5

Sample Output

1
2
1

HINT

n <= 40000, m <= 50000


对于众数,有一个性质。集合A和集合B的众数,要么是集合A的众数,要么是集合B中出现过的数。

根据这个性质我们考虑分块。

先将权值离散化,处理出前缀桶C[i][j]表示1~i块j数出现的次数。

在处理出mode[i][j]表示i块到j块的众数,这两个都可以在O(nsqrt(n))的时间内处理出来。

查询时众数来源有两个,所有整块的众数和零散块内出现过的数。

把零散的每个数统计一下,用桶可以O(1)得到答案。

代码:

#include <stdio.h>
#include <string.h>
#include <algorithm>
#include <math.h>
using namespace std;
#define N 40050
struct A {
int num,id,v;
}a[N];
bool cmp1(const A &x,const A &y){return x.num<y.num;}
bool cmp2(const A &x,const A &y){return x.id<y.id;}
int n,m,block,pos[N],L[250],R[250],size,mode[250][250],C[250][N],mp[N],times[250][250],ans;
int h[N];
void solve(int l,int r) {
int p=pos[l],q=pos[r];
int md=0,i;
if(p==q||p+1==q) {
for(i=l;i<=r;i++) {
h[a[i].v]++;
if(h[a[i].v]>h[md]||(h[a[i].v]==h[md]&&a[i].v<md))
md=a[i].v;
}
for(i=l;i<=r;i++) {
h[a[i].v]=0;
}
ans=mp[md];
return ;
}
int nowmode=mode[p+1][q-1],mtimes=times[p+1][q-1];
h[nowmode]=mtimes;
int tmp=nowmode;
//printf("nowmode=%d, mtimes=%d\n",nowmode,mtimes);
for(i=l;i<=R[p];i++) {
if(!h[a[i].v]) {
h[a[i].v]=C[q-1][a[i].v]-C[p][a[i].v];
}
h[a[i].v]++;
//printf("a[i].v=%d h[a[i].v]=%d\n",a[i].v,h[a[i].v]);
if(h[a[i].v]>mtimes||(h[a[i].v]==mtimes&&a[i].v<nowmode)) {
mtimes=h[a[i].v]; nowmode=a[i].v;
}
}
for(i=L[q];i<=r;i++) {
if(!h[a[i].v]) {
h[a[i].v]=C[q-1][a[i].v]-C[p][a[i].v];
}
h[a[i].v]++;
if(h[a[i].v]>mtimes||(h[a[i].v]==mtimes&&a[i].v<nowmode)) {
mtimes=h[a[i].v]; nowmode=a[i].v;
}
}
for(i=l;i<=R[p];i++) h[a[i].v]=0;
for(i=L[q];i<=r;i++) h[a[i].v]=0;
h[tmp]=0;
ans=mp[nowmode];
}
int main() {
scanf("%d%d",&n,&m);
int i,j,k,x,y;
for(i=1;i<=n;i++) scanf("%d",&a[i].num),a[i].id=i;
sort(a+1,a+n+1,cmp1); a[0].num=342344354;
for(i=1,j=0;i<=n;i++) {
if(a[i].num!=a[i-1].num) j++;
a[i].v=j;
mp[j]=a[i].num;
}
sort(a+1,a+n+1,cmp2);
size=sqrt(n);
block=n/size;
for(i=1;i<=block;i++) {
L[i]=R[i-1]+1; R[i]=i*size;
for(j=L[i];j<=R[i];j++) {
pos[j]=i;
/*if(!C[i][a[j].v]) {
C[i][a[j].v]=C[i-1][a[j].v];
}*/
C[i][a[j].v]++;
}
for(j=1;j<=R[i];j++) {
C[i+1][a[j].v]=C[i][a[j].v];
}
}
if(R[block]!=n) {
block++; L[block]=R[block-1]+1; R[block]=n;
for(i=L[block];i<=n;i++) {
pos[i]=block;
/*if(!C[block][a[i].v]) {
C[block][a[i].v]=C[block-1][a[i].v];
}*/
C[block][a[i].v]++;
}
}
for(i=1;i<=block;i++) {
int md=0;
for(j=L[i];j<=R[i];j++) {
if(C[i][a[j].v]-C[i-1][a[j].v]>C[i][md]-C[i-1][md]||(C[i][a[j].v]-C[i-1][a[j].v]==C[i][md]-C[i-1][md]&&a[j].v<md))
md=a[j].v;
}
mode[i][i]=md; times[i][i]=C[i][md]-C[i-1][md];
for(j=i+1;j<=block;j++) {
int md=mode[i][j-1];
for(k=L[j];k<=R[j];k++) {
if(C[j][a[k].v]-C[i-1][a[k].v]>C[j][md]-C[i-1][md]||(C[j][a[k].v]-C[i-1][a[k].v]==C[j][md]-C[i-1][md]&&a[k].v<md))
md=a[k].v;
}
mode[i][j]=md; times[i][j]=C[j][md]-C[i-1][md];
}
}
//for(i=1;i<=n;i++) printf("i=%d pos[i]=%d\n",i,pos[i]);
while(m--) {
scanf("%d%d",&x,&y);
x=(x+ans-1)%n+1; y=(y+ans-1)%n+1;
if(x>y) swap(x,y);
solve(x,y);
printf("%d\n",ans);
}
}

BZOJ_2724_[Violet 6]蒲公英_分块的更多相关文章

  1. [BZOJ 2724] [Violet 6] 蒲公英 【分块】

    题目链接:BZOJ - 2724 题目分析 这道题和 BZOJ-2821 作诗 那道题几乎是一样的,就是直接分块,每块大小 sqrt(n) ,然后将数字按照数值为第一关键字,位置为第二关键字排序,方便 ...

  2. BZOJ.2724.[Violet 6]蒲公英(静态分块)

    题目链接 区间众数 强制在线 考虑什么样的数会成为众数 如果一个区间S1的众数为x,那么S1与新区间S2的并的众数只会是x或S2中的数 所以我们可以分块先预处理f[i][j]表示第i到第j块的众数 对 ...

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

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

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

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

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

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

  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. 「Violet」蒲公英

    「Violet」蒲公英 传送门 区间众数,强制在线. 分块经典题. 像这题一样预处理,然后就直接爆搞,复杂度 \(O(n \sqrt n)\) 参考代码: #include <algorithm ...

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

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

  9. [BZOJ2724][Violet 6]蒲公英

    [BZOJ2724][Violet 6]蒲公英 试题描述 输入 修正一下 l = (l_0 + x - 1) mod n + 1, r = (r_0 + x - 1) mod n + 1 输出 输入示 ...

随机推荐

  1. 重写,string创建内存问题

     //重写equals方法,因为我们要对比的是date类中的时间而不是对象的引用地址 51     //如果传递的是Object类的话,我们就需要重写hashCode()方法,这样就比较麻烦,而且暂时 ...

  2. Python高阶函数之 - 装饰器

    高阶函数:  1. 函数名可以作为参数传入     2. 函数名可以作为返回值. python装饰器是用于拓展原来函数功能的一种函数 , 这个函数的特殊之处在于它的返回值也是一个函数 , 使用pyth ...

  3. iOS9自动布局神器StackView

    http://www.jianshu.com/p/767f72b7d754 这篇文章紧跟上边autolayout的一些小技巧,如果你没有看过,不防先看下<你真的会用autolayout吗?> ...

  4. txtbook简单HTML可读化改造

    一般来讲下载的txtbook在notepad或者之类的文本编辑器下的阅读体验不是很好,PC上面专门装个txt阅读器好像有点杀鸡用牛刀,可以用HTML简单处理一下就可以放在浏览器下爽快的阅读了,这个操作 ...

  5. 通知:QQ互联网回调地址校验加强

    今天公司网站第三方qq快捷登录突然登录不了了,之前明明是ok的. 可以看到有一个错误信息提示 在qq互联的官网看到了这个通知 然后解决办法是: 1.打开http://open.qq.com/tools ...

  6. java之Spring(AOP)前奏-动态代理设计模式(上)

    我们常常会遇到这样的事,项目经理让你为一个功能类再加一个功能A,然后你加班为这个类加上了功能A: 过了两天又来了新需求,再在A功能后面加上一个新功能B,你加班写好了这个功能B,加在了A后面:又过 了几 ...

  7. Lintcode400 Maximum Gap solution 题解

    [题目描述] Given an unsorted array, find the maximum difference between the successive elements in its s ...

  8. (四)SpringBoot2.0基础篇- 多数据源,JdbcTemplate和JpaRepository

    在日常开发中,经常会遇到多个数据源的问题,而SpringBoot也有相关API:Configure Two DataSources:https://docs.spring.io/spring-boot ...

  9. Django入门四之数据库相关

    1. 数据库设置 在settings.py中配置数据库 我首先使用的是sqlite3,所以配置如下 2. 数据库的数据结构定义 #blog/models.py #定义了一个表(Student),表里两 ...

  10. 1 Numpy-科学计算

    在Python中,使用list可以保存一组值,可以作为数组使用,但是比较浪费内存和时间.类似的array模块,不支持多维,也没有各种函数运算,因此也极其不方便. 为解决这一问题,Python提供了Nu ...