博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
【bzoj2724】蒲公英(分块)
阅读量:4348 次
发布时间:2019-06-07

本文共 2641 字,大约阅读时间需要 8 分钟。

题目分析

付费题哈哈。题意就是求区间众数,由于区间众数无法快速合并,所以不能使用传统的数据结构如线段树等。

这时分块就能派上很大的用场。将序列分成$\sqrt{n}+$块,每块大小$\sqrt{n}+$,通过预处理得到cnt[i][j], ans[i][j]分别表示i在前j块中出现的次数,和第i块到第j块的众数是多少。

那么查询时我们就得到了至多$\sqrt{n}$个连续的块,和至多$2\sqrt{n}$个零散的元素,对于零散的元素,暴力,对于连续的块,直接使用预处理。

code

#include
#include
#include
#include
#include
#include
#include
using namespace std; const int N = 4e4 + 5, oo = 0x7fffffff;int n, m, S;int val[N], num[N], len;int blk[N], bl[300], br[300], blkCnt, sum[N];int ans[300][300], cnt[N][300]; int read(){ int i=0,f=1;char ch; for(ch=getchar();(ch<'0'||ch>'9')&&ch!='-';ch=getchar()); if(ch=='-') {f=-1;ch=getchar();} for(;ch>='0'&&ch<='9';ch=getchar()) i=(i<<3)+(i<<1)+(ch^48); return f*i;} inline void wr(int x){ if(x < 0) putchar('-'), x = -x; if(x > 9) wr(x / 10); putchar(x % 10 + '0');} inline void disc_init(){ sort(num + 1, num + len + 1); len = unique(num + 1, num + len + 1) - (num + 1); for(int i = 1; i <= n; i++) val[i] = lower_bound(num + 1, num + len + 1, val[i]) - num;// for(int i = 1; i <= n; i++) cout<
<
maxx) maxx = ret, cur = val[k]; else if(ret == maxx && val[k] < cur) cur = val[k]; } ans[i][j] = cur; } }} inline int query(int l, int r){ if(l > r) swap(l, r); int blk_L = blk[l] + 1, blk_R = blk[r] - 1; if(bl[blk_L - 1] == l) blk_L--; if(br[blk_R + 1] == r) blk_R++; if(blk_L > blk_R){ int sum[N] = { 0}, maxx = -oo, ret = oo; for(int i = l; i <= r; i++){ int c = ++sum[val[i]]; if(c > maxx) maxx = c, ret = val[i]; else if(c == maxx && val[i] < ret) ret = val[i]; } return ret; } int ret = ans[blk_L][blk_R], sum[N] = { 0}, ret_cnt = cnt[ret][blk_R] - cnt[ret][blk_L - 1]; for(int i = l; i < bl[blk_L]; i++){ int c; if(sum[val[i]]) c = ++sum[val[i]]; else{ sum[val[i]] = cnt[val[i]][blk_R] - cnt[val[i]][blk_L - 1]; c = ++sum[val[i]]; } if(c > ret_cnt) ret = val[i], ret_cnt = c; else if(c == ret_cnt && val[i] < ret) ret = val[i]; } for(int i = br[blk_R] + 1; i <= r; i++){ int c; if(sum[val[i]]) c = ++sum[val[i]]; else{ sum[val[i]] = cnt[val[i]][blk_R] - cnt[val[i]][blk_L - 1]; c = ++sum[val[i]]; } if(c > ret_cnt) ret = val[i], ret_cnt = c; else if(c == ret_cnt && val[i] < ret) ret = val[i]; } return ret;} int main(){ //freopen("h.in","r",stdin); n = read(), m = read(); S = 400; for(int i = 1; i <= n; i++) val[i] = num[++len] = read(); disc_init(); initBlk(); initData(); int ans = 0; for(int i = 1; i <= m; i++){ int l = read(), r = read(); l = (l + ans - 1) % n + 1, r = (r + ans - 1) % n + 1; wr(ans = num[query(l, r)]), putchar('\n'); } return 0;}

转载于:https://www.cnblogs.com/CzYoL/p/7257855.html

你可能感兴趣的文章
08.CXF发布WebService(Java项目)
查看>>
java-集合框架
查看>>
RTMP
查看>>
求一个数的整数次方
查看>>
点云PCL中小细节
查看>>
铁路信号基础
查看>>
RobotFramework自动化2-自定义关键字
查看>>
CMU Bomblab 答案
查看>>
技术分析淘宝的超卖宝贝
查看>>
Azure云服务托管恶意软件
查看>>
My安卓知识6--关于把项目从androidstudio工程转成eclipse工程并导成jar包
查看>>
旧的起点(开园说明)
查看>>
生产订单“生产线别”带入生产入库单
查看>>
crontab导致磁盘空间满问题的解决
查看>>
自定义滚动条
查看>>
APP开发手记01(app与web的困惑)
查看>>
初识前端作业1
查看>>
ffmpeg格式转换命令
查看>>
万方数据知识平台 TFHpple +Xpath解析
查看>>
【转】判断点在多边形内(matlab)
查看>>