发现写算法专题老是写不动,,,,

所以就先把我在luogu上的题解搬过来吧!

题目大意:查询区间众数,无修改,强制在线

乍一看是一道恐怖的题,仔细一看发现并没有那么难;

大致思路是这样的,首先我们要充分发挥分块暴力大法好的精神

先暴力预处理出每个块内每种蒲公英的个数,

然后求出对每个块而言的前缀和,

于是这样我们就可以区间查询任意两个块之间每种蒲公英的数量了

然后我们预处理出任意两个块之间的众数

最后对于每组询问,我们先找到夹在它们中间的块,

如果这个两个块r-l<=1,那么我们暴力求众数

为什么? 因为不这样的话,万一x,y在一个快,那么r可能会比l小,要特判

如果x,y隔得很近,同样有各种奇奇怪怪的情况要做特判,

那既然这么麻烦,我们不如直接暴力搞是吧。

如果两个块相差超过了1,那么我们先取出中间块的众数,作为我们的answer,然后对旁边两个块暴力处理众数(此处注意判断时要加上中间的蒲公英)。

最后我们就得到了答案,

但是注意到ai的范围很大,所以我们需要离散化。

并且由于数量相同时要优先编号小的,于是我们处理众数的时候要多加这个判断

基本就是这样了。。。

表示本蒟蒻一A过了还是很开心的(^▽^)(虽然说第一次交没删调试结果too many or too few lines 了,但是去掉调试就过了,也可以算是一A嘛是吧)

下面代码:

 #include<bits/stdc++.h>
using namespace std;
#define R register int
#define AC 40100
#define ac 210
#define D printf("line in %d\n",__LINE__);
int block,n,m,answer,tot;
int s[AC];
struct abc{
int num,w,x;
}b[AC];//原数列+离散化后数组
int sum[ac][AC];//每种数字块内前缀和
int ans[ac][ac];//任意两块之间的众数
int belong[AC];//所属块
int color[AC]; inline int read()
{
int x=;char c=getchar();
while(c>'' || c<'') c=getchar();
while(c>='' && c<='') x=x*+c-'',c=getchar();
return x;
} bool cmp1(abc a,abc b)
{
return a.w < b.w;
} bool cmp2(abc a,abc b)
{
return a.num < b.num;
} void search(int x,int y)
{
// printf("%d %d\n",x,y);
int l=x/block + ,r=y/block - ;//取出中间块
if(r - l <= )//如果x,y相差很小,那么暴力统计
{
answer=;
for(R i=x;i<=y;i++)
if((++color[b[i].x] > color[answer]) || (color[b[i].x] == color[answer] && b[i].x < answer)) answer=b[i].x;
for(R i=x;i<=y;i++)
--color[b[i].x];
printf("%d\n",s[answer]);
return ;
}
else//不然的话
{
int ll=l * block - ,rr=(r+) * block;
answer=ans[l][r];
for(R i=x;i<=ll;i++)
{
++color[b[i].x];
if(color[b[i].x] + sum[r][b[i].x] - sum[l-][b[i].x] > color[answer] + sum[r][answer] - sum[l-][answer]) answer=b[i].x;
else if(color[b[i].x] + sum[r][b[i].x] - sum[l-][b[i].x] == color[answer] + sum[r][answer] - sum[l-][answer] && b[i].x < answer) answer=b[i].x;//编号小也要优先,因为一行写不下,为了美观,,,就用else吧,不然就用||了
}
for(R i=rr;i<=y;i++)
{
++color[b[i].x];
if(color[b[i].x] + sum[r][b[i].x] - sum[l-][b[i].x] > color[answer] + sum[r][answer] - sum[l-][answer]) answer=b[i].x;
else if(color[b[i].x] + sum[r][b[i].x] - sum[l-][b[i].x] == color[answer] + sum[r][answer] - sum[l-][answer] && b[i].x < answer) answer=b[i].x;
}
for(R i=x;i<=ll;i++) --color[b[i].x];
for(R i=rr;i<=y;i++) --color[b[i].x];
printf("%d\n",s[answer]);
return ;
}
} void pre()//读入
{
n=read(),m=read();
block=sqrt(n);
for(R i=;i<=n;i++) b[i].w=read(),b[i].num=i;
sort(b+,b+n+,cmp1);
for(R i=;i<=n;i++)
{
if(b[i].w != b[i-].w)
{
s[++tot]=b[i].w;//存下对应新编号的对应真实编号
b[i].x=tot;
}
else b[i].x=b[i-].x;//离散化
}
sort(b+,b+n+,cmp2);
} void getsum()
{//注意0也被分在块0中
for(R i=;i<=n;i++)
{
belong[i]=i/block;
sum[belong[i]][b[i].x]++;
}
for(R i=;i<=belong[n];i++)
for(R j=;j<=tot;j++)
sum[i][j]+=sum[i-][j];
} void getans()
{
for(R i=;i<=belong[n];i++)
{
int be=i * block,now=;
if(!be) be=;//这里和作诗不同,因为这里的now要参与比较了,而不是单纯的统计,而now初始值为0,所以color[0]不能被修改
for(R j=be;j<=n;j++)
{
if((++color[b[j].x] > color[now]) || (color[b[j].x] == color[now] && b[j].x < now)) now=b[j].x;//更新ans
ans[i][belong[j]]=now;//存下新ans
}
for(R j=be;j<=n;j++) --color[b[j].x];//暴力撤销
}
/*for(R i=0;i<=belong[n];i++)
{
for(R j=i;j<=belong[n];j++)
printf("%d ",ans[i][j]);
printf("\n");
}*/
} void work()//预处理出前缀和和众数
{
int a,b;
for(R i=;i<=m;i++)
{
a=(read() + s[answer] -) % n + ,b=(read() + s[answer] - ) % n + ;//获取询问
if(a < b) search(a,b);
else search(b,a);//因为经过了运算,所以大小顺序就可能改变了
}
} int main()
{
// freopen("in.in","r",stdin);
pre();
getsum();
getans();
work();
// fclose(stdin);
return ;
}

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

  1. BZOJ2724 [Violet]蒲公英 分块

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

  2. Luogu P4168 [Violet]蒲公英 分块

    这道题算是好好写了.写了三种方法. 有一个好像是$qwq$$N\sqrt(N)$的方法,,但是恳请大佬们帮我看看为什么这么慢$qwq$(后面的第三种) 注:$pos[i]$表示$i$属于第$pos[i ...

  3. 洛谷 P4168 [Violet]蒲公英 解题报告

    P4168 [Violet]蒲公英 题目背景 亲爱的哥哥: 你在那个城市里面过得好吗? 我在家里面最近很开心呢.昨天晚上奶奶给我讲了那个叫「绝望」的大坏蛋的故事的说!它把人们的房子和田地搞坏,还有好多 ...

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

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

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

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

  6. BZOJ 2724: [Violet 6]蒲公英 [分块 区间众数]

    传送门 题面太美不忍不放 分块分块 这种题的一个特点是只有查询,通常需要预处理:加入修改的话需要暴力重构预处理 预处理$f[i][j]$为第i块到第j块的众数,显然$f[i][j]=max{f[i][ ...

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

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

  8. BZOJ2724 [Violet]蒲公英(分块)

    区间众数.分块,预处理任意两块间所有数的众数,和每块中所有数的出现次数的前缀和.查询时对不是整块的部分暴力,显然只有这里出现的数可能更新答案.于是可以优美地做到O(n√n). #include< ...

  9. p4168 [Violet]蒲公英(分块)

    区间众数的重题 和数列分块入门9双倍经验还是挺好的 然后开O2水过 好像有不带log的写法啊 之后在补就是咕咕咕 // luogu-judger-enable-o2 #include <cstd ...

随机推荐

  1. swift实现UItableview上拉下拉刷新模块

    最近用写个项目 发现上拉下拉刷新模块没找到合适的 so 自己写了一个 由于最近忙 教程就不写了 里面有 直接贴地址https://github.com/DaChengTechnology/DCRefr ...

  2. 小计Tomcat的调优思路

    描述 最近在补充自己的短板,刚好整理到Tomcat调优这块,基本上面试必问,于是就花了点时间去搜集一下tomcat调优 都调了些什么,先记录一下调优手段,更多详细的原理和实现以后用到时候再来补充记录, ...

  3. Django之视图系统

    Django的View(视图) 一个视图函数(类),简称视图,是一个简单的python函数(类),它接受web请求并返回web响应. 响应可以是一张网页的HTML内容,一个重定向,一个404错误,或者 ...

  4. PHPCMS如何让手机站点取消浏览大图直接加载原图

    一.然后找到phpcms\modules\wap\functions\global.func.php 文件,找到相关代码,如下图: return '<img src="'.thumb( ...

  5. [python] Queue.Queue vs. collections.deque

    https://stackoverflow.com/questions/717148/queue-queue-vs-collections-deque/717199#717199 Queue,Queu ...

  6. 简析Monte Carlo与TD算法的相关问题

    Monte Carlo算法是否能够做到一步更新,即在线学习? 答案显然是不能,如果可以的话,TD算法还有何存在的意义?MC算法必须要等到episode结束后才可以进行值估计的主要原因在于对Return ...

  7. website for personal research

    YOLO https://pjreddie.com/darknet/yolo/ Low Rank Matrix Recovery and Completion via Convex Optimizat ...

  8. Linux虚拟机centos系统安装

    linux 其他知识目录 安装完后如果虚拟机网络不通请参考:虚拟机网络不通故障解决 1.centos6.9安装 后面安装出了点问题,ip没有并且eth0网卡找不到,不过重新配置ifcfg-eth0后重 ...

  9. GitHub 的简单使用

    GitHub 的简单使用 2016-01-28 16:32:481909浏览1评论 一.Git 版本控制器 commit:做一个版本:commit new file:添加到版本中,下边填的是项目的描述 ...

  10. Beta冲刺第二周王者荣耀交流协会第三次会议

    1.例会照片: 成员王超,高远博,冉华,王磊,王玉玲,任思佳,袁玥全部到齐 master:袁玥 2.时间跨度: 2017年11月19日 17:00 — 17:11,总计11分钟. 3.地 点: 一食堂 ...