BZOJ2724 蒲公英


题目背景

亲爱的哥哥:

你在那个城市里面过得好吗?

我在家里面最近很开心呢。昨天晚上奶奶给我讲了那个叫「绝望」的大坏蛋的故事的说!它把人们的房子和田地搞坏,还有好多小朋友也被它杀掉了。我觉得把那么可怕的怪物召唤出来的那个坏蛋也很坏呢。不过奶奶说他是很难受的时候才做出这样的事的……

最近村子里长出了一大片一大片的蒲公英。一刮风,这些蒲公英就能飘到好远的地方了呢。我觉得要是它们能飘到那个城市里面,让哥哥看看就好了呢!

哥哥你要快点回来哦!

爱你的妹妹 Violet

Azure 读完这封信之后微笑了一下。

“蒲公英吗……”

题目描述

在乡下的小路旁种着许多蒲公英,而我们的问题正是与这些蒲公英有关。

为了简化起见,我们把所有的蒲公英看成一个长度为n的序列 (a1,a2..an)" role="presentation">(a1,a2..an)(a1,a2..an)其中 ai" role="presentation">aiai为一个正整数,表示第i棵蒲公英的种类编号。

而每次询问一个区间 [l,r],你需要回答区间里出现次数最多的是哪种蒲公英,如果有若干种蒲公英出现次数相同,则输出种类编号最小的那个。

注意,你的算法必须是在线的

输入输出格式

输入格式:

第一行两个整数 n,m ,表示有n株蒲公英,m 次询问。

接下来一行n个空格分隔的整数 ai" role="presentation">aiai ,表示蒲公英的种类

再接下来m 行每行两个整数 l0,r0" role="presentation">l0,r0l0,r0 ,我们令上次询问的结果为 x(如果这是第一次询问, 则 x=0)。

令l=(l0+x−1)modn+1,r=(r0+x−1)modn+1" role="presentation">l=(l0+x−1)modn+1,r=(r0+x−1)modn+1l=(l0+x−1)modn+1,r=(r0+x−1)modn+1 ,如果 l>r,则交换 l,r 。

最终的询问区间为[l,r]。

输出格式:

输出m 行。每行一个整数,表示每次询问的结果。

输入输出样例

输入样例#1

6 3

1 2 3 2 1 2

1 5

3 6

1 5

输出样例#1:

1

2

1

说明

对于 20% 的数据,保证 1≤n,m≤30001≤n,m≤3000" role="presentation">1≤n,m≤30001≤n,m≤30001≤n,m≤30001≤n,m≤3000。

对于 100% 的数据,保证 1≤n≤40000,1≤m≤50000,1≤ai≤109" role="presentation">1≤n≤40000,1≤m≤50000,1≤ai≤1091≤n≤40000,1≤m≤50000,1≤ai≤109


区间求众数

分块

cnt[i][j]" role="presentation">cnt[i][j]cnt[i][j]表示第i个数在前j个块中的数量

ans[i][j]" role="presentation">ans[i][j]ans[i][j]表示第i到第j个块中的众数

先离散,然后预处理cnt" role="presentation">cntcnt和ans" role="presentation">ansans,对于查询,先把答案设定为完整块的众数,不是完整块的部分就暴力枚举进行比较好了

时间&空间效率O(nsqrt(n))" role="presentation">O(nsqrt(n))O(nsqrt(n))


#include<bits/stdc++.h>
using namespace std;
#define N 210
#define M 40010
#define For(x,a,b) for(int x=a;x<=b;x++)
map<int,int> mp;
int n,m,tot=0,lastans=0;
int a[M],b[M],pre[M],t[N]={0};
int block[M],L[N],R[N];
int cnt[M][N]={0},ans[N][N]={0};
int calc(int id,int lb,int rb){
return cnt[id][rb]-cnt[id][lb-1];
}
void init(){
int siz=sqrt(n);
For(i,1,n)block[i]=(i-1)/siz+1;
int bsiz=block[n];
For(i,1,bsiz)L[i]=R[i-1]+1,R[i]=min(n,i*siz);
For(i,1,n)cnt[b[i]][block[i]]++;
For(i,1,tot)For(j,1,bsiz)cnt[i][j]+=cnt[i][j-1];
For(i,1,bsiz)
For(j,i,bsiz){
int tmp=ans[i][j-1];
For(k,L[j],R[j]){
int t1=calc(b[k],i,j),t2=calc(tmp,i,j);
if((t1==t2&&pre[b[k]]<pre[tmp])||t1>t2)tmp=b[k];
}
ans[i][j]=tmp;
}
}
bool check(int id,int tmp){
if(t[id]>t[tmp])return 1;
if(t[id]==t[tmp]&&pre[id]<pre[tmp])return 1;
return 0;
}
int solve(int l,int r){
int pl=block[n]+1,pr=0;
For(i,1,block[n])if(L[i]>=l)pl=min(pl,i);
For(i,1,block[n])if(R[i]<=r)pr=max(pr,i);
if(pl>pr){
int tmp=0;
For(i,l,r)t[b[i]]=0;
For(i,l,r)t[b[i]]++;
For(i,l,r)if(check(b[i],tmp))tmp=b[i];
return tmp;
}
int tmp=ans[pl][pr];
t[tmp]=calc(tmp,pl,pr);
For(i,l,L[pl]-1)t[b[i]]=calc(b[i],pl,pr);
For(i,R[pr]+1,r)t[b[i]]=calc(b[i],pl,pr);
For(i,l,L[pl]-1)t[b[i]]++;
For(i,R[pr]+1,r)t[b[i]]++;
For(i,l,L[pl]-1)if(check(b[i],tmp))tmp=b[i];
For(i,R[pr]+1,r)if(check(b[i],tmp))tmp=b[i];
return tmp;
}
int main(){
scanf("%d%d",&n,&m);
For(i,1,n){
scanf("%d",&a[i]);
if(!mp.count(a[i])){
mp[a[i]]=++tot;
pre[tot]=a[i];
}
b[i]=mp[a[i]];
}
init();
For(i,1,m){
int l,r;scanf("%d%d",&l,&r);
l=(l+lastans-1)%n+1;
r=(r+lastans-1)%n+1;
if(l>r)swap(l,r);
lastans=pre[solve(l,r)];
printf("%d\n",lastans);
}
return 0;
}

BZOJ2724 蒲公英 【分块】的更多相关文章

  1. [日常摸鱼]bzoj2724蒲公英-分块

    区间众数经典题~ http://begin.lydsy.com/JudgeOnline/problem.php?id=4839这里可以提交~ 题意大概就是没有修改的询问区间众数,如果有一样的输出最小的 ...

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

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

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

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

  4. 【bzoj2724】[Violet 6]蒲公英 分块+STL-vector

    题目描述 输入 修正一下 l = (l_0 + x - 1) mod n + 1, r = (r_0 + x - 1) mod n + 1 输出 样例输入 6 3 1 2 3 2 1 2 1 5 3 ...

  5. BZOJ2724 [Violet]蒲公英 分块

    题目描述 经典区间众数题目 然而是权限题,所以题目链接放Luogu的 题解 因为太菜所以只会$O(n*\sqrt{n}+n*\sqrt{n}*log(n))$的做法 就是那种要用二分的,并不会clj那 ...

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

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

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

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

  8. [Violet]蒲公英 分块

    发现写算法专题老是写不动,,,, 所以就先把我在luogu上的题解搬过来吧! 题目大意:查询区间众数,无修改,强制在线 乍一看是一道恐怖的题,仔细一看发现并没有那么难: 大致思路是这样的,首先我们要充 ...

  9. [BZOJ2724] 蒲公英

    题目背景 亲爱的哥哥: 你在那个城市里面过得好吗? 我在家里面最近很开心呢.昨天晚上奶奶给我讲了那个叫「绝望」的大坏蛋的故事的说!它把人们的房子和田地搞坏,还有好多小朋友也被它杀掉了.我觉得把那么可怕 ...

随机推荐

  1. codeforces27D Ring Road 2

    本文版权归ljh2000和博客园共有,欢迎转载,但须保留此声明,并给出原文链接,谢谢合作. 本文作者:ljh2000 作者博客:http://www.cnblogs.com/ljh2000-jump/ ...

  2. Android显示框架:自定义View实践之绘制篇

    文章目录 一 View 二 Paint 2.1 颜色处理 2.2 文字处理 2.3 特殊处理 三 Canvas 3.1 界面绘制 3.2 范围裁切 3.3 集合变换 四 Path 4.1 添加图形 4 ...

  3. intent Filter

    intent Filter 一.介绍 如果一个 Intent 请求在一片数据上执行一个动作, Android 如何知道哪个应用程序(和组件)能用来响应这个请求呢? Intent Filter就是 用来 ...

  4. nginx页面不能正常访问排除方法

    nginx页面不能访问 nginx页面不能访问 检查服务端服务是否启动成功 在服务端使用wget和curl测试下返回的是否正常 浏览器wget或者curl等软件访问不了Ngixn页面 1. 检查服务端 ...

  5. git 提交作业流程

    git 提交作业流程,主要分为4个步骤 # 拉取远程git最新版本到本地,每次都可以先执行这条命令,因为会有其他同学更新仓库 git pull # add需要上传的文件,那个文件修改或者新增的,就ad ...

  6. ItemsSource数据源 或 集合属性 的定义 ——> 的数据源定义(典型)

    在Xaml中: ItemsSource="{Binding Path=GridDataSource.PoliceforceDataSource}" 在ViewModel中: Obs ...

  7. Verilog HDL Test Bench

    As digital systems becomes more complex,it becomes increasingly important to verify the functionalit ...

  8. Highcharts 基本条形图;Highcharts 堆叠条形图;Highcharts 反向条形图

    Highcharts 基本条形图 配置 chart 配置 设置 chart 的 type 属性 为 bar ,chart.type 描述了图表类型.默认值为 "line". var ...

  9. 解决在for循环内判断条件多次执行

    最近遇到的这个问题,就是在for循环内if判断的条件会多次执行. 例如,在返回的30数据中,a条目是第7条则会进行30次判断,弹出29次查无数据,也就是要点击29次关闭alert,很是让人不爽. 有了 ...

  10. map、filter、reduce、lambda

    一.map.filter.reduce map(fuction , iterable) 映射 对可迭代对象中的每一项,使用函数去改变 filter(function, iterable) 过滤 可迭代 ...