BZOJ 2724: [Violet 6]蒲公英 [分块 区间众数]
题面太美不忍不放
.gif)
分块分块
这种题的一个特点是只有查询,通常需要预处理;加入修改的话需要暴力重构预处理
预处理$f[i][j]$为第i块到第j块的众数,显然$f[i][j]=max{f[i][j-1],j中出现的数}$,复杂度$O(N^2/S)$,常数比较小吧
最近用$pair$上瘾了...
然后查询$[l,r]$时,整块直接查,两边不完整的枚举出现的数,然后加上整块里出现次数来更新
求整块的出现次数,可以用$v[i]$表示数字$i$出现位置,二分来找,复杂度$O(NSlogN)$
或者clj orz的论文里还有预处理的方法,预处理$s[i][x]$前i个块x的次数和$ss[i][j][x]$第i块前j个中k出现次数,貌似代码量会很大....
所以说这种vector+二分来找一个区间内某个数出现次数还是比较巧妙的呀....
然后分块一定要分$\sqrt{\frac{N}{logN}}$大小,比根号快了1倍多.....
#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <cmath>
#include <vector>
using namespace std;
#define pii pair<int, int>
#define MP make_pair
#define fir first
#define sec second
const int N=4e4+,M=;
typedef unsigned long long ll;
inline int read(){
char c=getchar();int x=,f=;
while(c<''||c>''){if(c=='-')f=-;c=getchar();}
while(c>=''&&c<=''){x=x*+c-'';c=getchar();}
return x*f;
}
int n,Q,x,y,a[N],mp[N];
vector<int> v[N];
int pos[N],m,block;
struct _blo{int l,r;} b[M];
inline void ini(){
if(n==) block=;
else block=sqrt(n/log2(n));
m=(n-)/block+;
for(int i=;i<=n;i++) pos[i]=(i-)/block+;
for(int i=;i<=m;i++) b[i].l=(i-)*block+,b[i].r=i*block;
b[m].r=n;
}
//struct I{int x; bool operator <(const I &r) const{return x>r.x;} I(int a=0):x(a){} };
pii f[M][M];
int c[N];
struct Block{
void set(int x){
memset(c,,sizeof(c));
pii now(,);
for(int i=b[x].l;i<=n;i++){
c[a[i]]++; int t=pos[i];
now=max(now,MP( c[a[i]],-a[i] ) );//-a[i]
f[x][t]=now;
}
}
int cou(int l,int r,int x){
return upper_bound(v[x].begin(),v[x].end(),r) - lower_bound(v[x].begin(),v[x].end(),l);
}
int que(int l,int r){//printf("que %d %d\n",l,r);
pii re=f[pos[l]+][pos[r]-];
if(pos[l]==pos[r])
for(int i=l;i<=r;i++) re=max(re,MP( cou(l,r,a[i]),-a[i] ) );
else{
for(int i=l;i<=b[pos[l]].r;i++) re=max(re,MP( cou(l,r,a[i]),-a[i] ) );
for(int i=b[pos[r]].l;i<=r;i++) re=max(re,MP( cou(l,r,a[i]),-a[i] ) );
}
return -re.sec;
}
}B;
int main(){
freopen("in","r",stdin);
n=read();Q=read();
for(int i=;i<=n;i++) a[i]=mp[i]=read();
sort(mp+,mp++n); mp[]=unique(mp+,mp++n)-mp-;
for(int i=;i<=n;i++)
a[i]=lower_bound(mp+,mp++mp[],a[i])-mp , v[a[i]].push_back(i);
ini();
for(int i=;i<=m;i++) B.set(i);
int last=;
while(Q--){
int l=(read()+last-)%n+,r=(read()+last-)%n+;
if(l>r) swap(l,r);
last=mp[ B.que(l,r) ];
printf("%d\n",last);
}
}
7796ms
[2017-03-15 16:41:05]
又想了一下,$ss$其实不用预处理,查询的时候暴力算就行了
然后来享受没有$log$的优越,3372ms到第一页啦啦啦
#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <cmath>
using namespace std;
#define pii pair<int, int>
#define MP make_pair
#define fir first
#define sec second
const int N=4e4+,M=;
typedef unsigned long long ll;
inline int read(){
char c=getchar();int x=,f=;
while(c<''||c>''){if(c=='-')f=-;c=getchar();}
while(c>=''&&c<=''){x=x*+c-'';c=getchar();}
return x*f;
}
int n,Q,x,y,a[N],mp[N];
int pos[N],m,block;
struct _blo{int l,r;} b[M];
inline void ini(){
block=sqrt(n);
m=(n-)/block+;
for(int i=;i<=n;i++) pos[i]=(i-)/block+;
for(int i=;i<=m;i++) b[i].l=(i-)*block+,b[i].r=i*block;
b[m].r=n;
} pii f[M][M];
int c[N],s[M][N];
struct Block{
void set(int x){
memset(c,,sizeof(c));
pii now(,);
for(int i=b[x].l;i<=n;i++){
c[a[i]]++; int t=pos[i];
now=max(now,MP( c[a[i]],-a[i] ) );
f[x][t]=now;
}
for(int i=;i<=mp[];i++) s[x][i]=s[x-][i];
for(int i=b[x].l;i<=b[x].r;i++) s[x][a[i]]++;
} int t[N];
int que(int l,int r){
pii re=f[pos[l]+][pos[r]-];
if(pos[l]==pos[r]){
for(int i=l;i<=r;i++) t[a[i]]=;
for(int i=l;i<=r;i++) re=max(re,MP( ++t[a[i]],-a[i] ) );
}else{
int L=pos[l],R=pos[r]-;
for(int i=l;i<=b[pos[l]].r;i++) t[a[i]]=s[R][ a[i] ] - s[L][ a[i] ];
for(int i=b[pos[r]].l;i<=r;i++) t[a[i]]=s[R][ a[i] ] - s[L][ a[i] ];
for(int i=l;i<=b[pos[l]].r;i++) re=max(re,MP( ++t[a[i]],-a[i] ) );
for(int i=b[pos[r]].l;i<=r;i++) re=max(re,MP( ++t[a[i]],-a[i] ) );
}
return -re.sec;
}
}B;
int main(){
freopen("in","r",stdin);
n=read();Q=read();
for(int i=;i<=n;i++) a[i]=mp[i]=read();
sort(mp+,mp++n); mp[]=unique(mp+,mp++n)-mp-;
for(int i=;i<=n;i++)
a[i]=lower_bound(mp+,mp++mp[],a[i])-mp; ini();
for(int i=;i<=m;i++) B.set(i);
int last=;
while(Q--){
int l=(read()+last-)%n+,r=(read()+last-)%n+;
if(l>r) swap(l,r);
last=mp[ B.que(l,r) ];
printf("%d\n",last);
}
}
BZOJ 2724: [Violet 6]蒲公英 [分块 区间众数]的更多相关文章
- 【BZOJ 2724】 2724: [Violet 6]蒲公英 (区间众数不带修改版本)
2724: [Violet 6]蒲公英 Time Limit: 40 Sec Memory Limit: 512 MBSubmit: 1908 Solved: 678 Description In ...
- BZOJ 2724: [Violet 6]蒲公英( 分块 )
虽然AC了但是时间惨不忍睹...不科学....怎么会那么慢呢... 无修改的区间众数..分块, 预处理出Mode[i][j]表示第i块到第j块的众数, sum[i][j]表示前i块j出现次数(前缀和, ...
- BZOJ 2724 [Violet 6]蒲公英(分块)
题意 在线区间众数 思路 预处理出 f[i][j] 即从第 i 块到第 j 块的答案.对于每个询问,中间的整块直接用预处理出的,两端的 sqrtn 级别的数暴力做,用二分查找它们出现的次数.每次询问的 ...
- bzoj2724: [Violet 6]蒲公英 分块 区间众数 论algorithm与vector的正确打开方式
这个,要处理各个数的话得先离散,我用的桶. 我们先把每个块里的和每个块区间的众数找出来,那么在查询的时候,可能成为[l,r]区间的众数的数只有中间区间的众数和两边的数. 证明:若不是这里的数连区间的众 ...
- BZOJ 2724: [Violet 6]蒲公英
2724: [Violet 6]蒲公英 Time Limit: 40 Sec Memory Limit: 512 MBSubmit: 1633 Solved: 563[Submit][Status ...
- [BZOJ 2724] [Violet 6] 蒲公英 【分块】
题目链接:BZOJ - 2724 题目分析 这道题和 BZOJ-2821 作诗 那道题几乎是一样的,就是直接分块,每块大小 sqrt(n) ,然后将数字按照数值为第一关键字,位置为第二关键字排序,方便 ...
- BZOJ.2724.[Violet 6]蒲公英(静态分块)
题目链接 区间众数 强制在线 考虑什么样的数会成为众数 如果一个区间S1的众数为x,那么S1与新区间S2的并的众数只会是x或S2中的数 所以我们可以分块先预处理f[i][j]表示第i到第j块的众数 对 ...
- 【刷题】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 ...
- 【BZOJ】2724: [Violet 6]蒲公英
2724: [Violet 6]蒲公英 Time Limit: 40 Sec Memory Limit: 512 MBSubmit: 2900 Solved: 1031[Submit][Statu ...
随机推荐
- hdu_5104 Primes Problem()
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=5104 rimes Problem Time Limit: 2000/1000 MS (Java/Oth ...
- [国嵌攻略][164][USB驱动程序设计]
USB驱动模型 1.USB host controller driver(主控器驱动):为USB主控制器提供驱动程序 2.USB core(USB核心):连接USB主控制器驱动和USB设备驱动 3.U ...
- LockSupport理解
一.背景 在看并发包源码的时候看见过LockSupport,今天恰巧看到LockSupport字眼,于是看下jdk1.7中的源码结构.想着它应该是运用多线程的锁工具的,到底似乎怎么实现的呢? 二.使用 ...
- HDU 4034 Graph(Floyd变形——逆向判断)
题目链接: http://acm.hdu.edu.cn/showproblem.php?pid=4034 Problem Description Everyone knows how to calcu ...
- 跟我一起读postgresql源码(十三)——Executor(查询执行模块之——Join节点(上))
Join节点 JOIN节点有以下三种: T_NestLoopState, T_MergeJoinState, T_HashJoinState, 连接类型节点对应于关系代数中的连接操作,PostgreS ...
- HTML5 Canvas圆盘抽奖应用(适用于Vue项目)
<!DOCTYPE html> <html lang="zh-cn"> <head> <meta charset="UTF-8& ...
- PHP过滤指定字符串,过滤危险字符
安全过滤函数,用于过滤危险字符 function safe_replace($string) { $string = str_replace(' ','',$string); $string = ...
- python-虎扑爬虫
Python作为一个高级编程语言,不知从何时起就在圈子里流行起来了.个人也是图个鲜,跟上时代步伐学习了一下."鲁迅"说过:不能学以致用,就是耍流氓.我用python对虎扑论坛作了一 ...
- winform程序压缩文件上传,服务器端asp.net mvc进行接收解压
期间编程没什么难度,唯一可能忽略导致结果失败是asp.net mvc配置 对于压缩文件大的话,需要配置mvc的最大接收量: <system.web> <httpRuntime ma ...
- FORTH运算符
body, table{font-family: 微软雅黑} table{border-collapse: collapse; border: solid gray; border-width: 2p ...