传送门

题目要求求出给定区间内编号最小的众数,强制在线。

虽然说这是个黑题……不过我们可以用暴力分块解决它。首先先对所有数离散化,这个不影响众数。我们先预处理出每个数在前i个块内出现了多少次,再预处理出块i到块j内最小众数是谁。前者很好预处理,后者的话,我们只要固定i,之后向后枚举,每次新加入一个数的时候就比较出现最多次的元素来更新当前众数。如果到了块末尾,就更新块的答案。

查询的时候,整块的我们直接去计算过的答案,之后对于每一个出现在零散位置的元素,我们记录下来,之后计算他们在整块中出现了多少次(前缀和相减即可),这样比较出出现次数最多的元素就可以。

这题的处理稍微有点复杂,我的做法是开个栈来记录当前出现在零散位置的元素。

看一下代码。

#include<cstdio>
#include<algorithm>
#include<cstring>
#include<iostream>
#include<cmath>
#include<set>
#include<queue>
#define rep(i,a,n) for(int i = a;i <= n;i++)
#define per(i,n,a) for(int i = n;i >= a;i--)
#define enter putchar('\n') using namespace std;
typedef long long ll;
const int M = ;
const int N = ;
const int INF = ; int read()
{
int ans = ,op = ;
char ch = getchar();
while(ch < '' || ch > '')
{
if(ch == '-') op = -;
ch = getchar();
}
while(ch >= '' && ch <= '')
{
ans *= ;
ans += ch - '';
ch = getchar();
}
return ans * op;
} int n,m,B,a[M],l[N],r[N],sum[M][N],ans[N][N],x,y,last,b[M],cnt,blo[M],tot,g = ,cur[M],maxx;
int sta[M],top,mpos; void init()
{
rep(i,,cnt)
{
rep(j,,n) sum[j][i] += sum[j][i-];
rep(j,l[i],r[i]) sum[a[j]][i]++;
}
rep(i,,cnt)
{
memset(cur,,sizeof(cur)),maxx = mpos = ,g = i;
rep(j,l[i],n)
{
cur[a[j]]++;
if(cur[a[j]] > maxx) maxx = cur[a[j]],mpos = a[j];
else if(cur[a[j]] == maxx && a[j] < mpos) mpos = a[j];
if(j == r[g]) ans[i][g] = mpos,g++;
}
}
} int query(int x,int y)
{
memset(cur,,sizeof(cur)),maxx = mpos = ;
int L = blo[x],R = blo[y];
if(L == R)
{
rep(i,x,y)
{
cur[a[i]]++;
if(cur[a[i]] > maxx) maxx = cur[a[i]],mpos = a[i];
else if(cur[a[i]] == maxx && a[i] < mpos) mpos = a[i];
}
return mpos;
}
int p = ans[L+][R-],now = sum[p][R-] - sum[p][L];
rep(i,x,r[L])
{
if(!cur[a[i]]) sta[++top] = a[i];
cur[a[i]]++;
}
rep(i,l[R],y)
{
if(!cur[a[i]]) sta[++top] = a[i];
cur[a[i]]++;
}
mpos = p;
while(top)
{
int k = sta[top],q = sum[k][R-] - sum[k][L] + cur[k];
if(q > now) now = q,mpos = k;
else if(q == now && k < mpos) mpos = k;
top--;
}
return mpos;
} int main()
{
n = read(),m = read(),B = sqrt(n);
cnt = (n % B) ? n / B + : n / B;
rep(i,,cnt) l[i] = r[i-] + ,r[i] = l[i] + B - ;
r[cnt] = n;
rep(i,,n) a[i] = b[i] = read();
sort(b+,b++n),tot = unique(b+,b++n) - b - ;
rep(i,,n) a[i] = lower_bound(b+,b++tot,a[i]) - b;
//rep(i,1,n) printf("%d ",a[i]);enter;
rep(i,,n)
{
blo[i] = g;
if(i == r[g]) g++;
}
init();
rep(i,,m)
{
x = read(),y = read();
x = (x + last - ) % n + ,y = (y + last - ) % n + ;
if(x > y) swap(x,y);
last = b[query(x,y)];
printf("%d\n",last);
}
return ;
}

Violet蒲公英的更多相关文章

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

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

  2. 【luogu1468】[Violet]蒲公英--求区间众数

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

  3. [Violet]蒲公英 分块

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

  4. P4168 [Violet]蒲公英 区间众数

    $ \color{#0066ff}{ 题目描述 }$ 在乡下的小路旁种着许多蒲公英,而我们的问题正是与这些蒲公英有关. 为了简化起见,我们把所有的蒲公英看成一个长度为n的序列 \((a_1,a_2.. ...

  5. 洛谷 P4168 [Violet] 蒲公英

    历尽千辛万苦终于AC了这道题目... 我们考虑1个区间\([l,r]\), 被其完整包含的块的区间为\([L,R]\) 那么众数的来源? 1.\([l,L)\)或\((R,r]\)中出现的数字 2.\ ...

  6. P4168 [Violet]蒲公英

    神仙分块题?其实还是很简单的,res[i][j]表示第i块到第j块的众数,然后再用sum[i][j]表示前i块中j这个种类出现的次数,然后分块瞎搞就行了,感觉我写的十分简洁,好评( //author ...

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

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

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

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

  9. BZOJ2724 [Violet]蒲公英 分块

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

  10. [Violet]蒲公英

    description 在线询问区间众数. data range \[n\le 40000,m\le 50000,a_i\le 10^9\] solution 自己分块不行于是\(\%\)了\(yyb ...

随机推荐

  1. Python的另一种开发环境--Anaconda中的Spyder

    本文作者LucyGill,转载请注明出处(虽然我觉得并不会有人转载). 刚开始学Python的时候,我用的是其自带的idle(安装Python后,在开始菜单里可以找到),后来发现在eclipse中设置 ...

  2. Codeforces 659F Polycarp and Hay【BFS】

    有毒,自从上次选拔赛(哭哭)一个垃圾bfs写错之后,每次写bfs都要WA几发...好吧,其实也就这一次... 小白说的对,还是代码能力不足... 非常不足... 题目链接: http://codefo ...

  3. ABP每次生成前都执行bundle设置

    ABP项目每次编译mvc项目时都会执行bundle,比较耗时. 可以在项目文件(*.csproj)中发现设置了每前生成前执行的命令 <Target Name="PreBuild&quo ...

  4. 如何用grep命令同时显示“匹配行”上下的n行?

    如何用grep命令同时显示匹配行上下的n行   标准unix/linux下的grep通过以下参数控制上下文 grep -C 5 foo file 显示file文件中匹配foo字串那行以及上下5行gre ...

  5. 【转】c++内存管理学习纲要

    http://blog.csdn.net/zhanghefu/article/details/5003407 转自:http://blog.csdn.net/wdzxl198/article/deta ...

  6. 【scrapy】Item及Spider

    Items Item objects are simple containers used to collect the scraped data.They provide a dictionary- ...

  7. topcoder srm 610

    div1 250pt: 题意:100*100的01矩阵,找出来面积最大的“类似国际象棋棋盘”的子矩阵. 解法:枚举矩阵宽(水平方向)的起点和终点,然后利用尺取法来找到每个固定宽度下的最大矩阵,不断更新 ...

  8. 分享codeigniter框架,在zend studio 环境下的代码提示

    一.到github下载相关文件 https://github.com/Stunt/Codeigniter-autocomplete 二.把文件放到application/config中 代码提示就出来 ...

  9. Oracle APEX 4.2安装和配置

    A standard Oracle 11.2.0.3 database installation comes bundled with Application Express (APEX) 3.2.1 ...

  10. HDU1542Atlantis(扫描线)

    HDU1542Atlantis(扫描线) 题目链接 题目大意:给你n个覆盖矩形,问最后覆盖的面积. 解题思路:将每一个矩形拆成两条线段,一条是+1的,还有一条是减1的.然后扫描先从上往下扫描,碰到加1 ...