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 ...
随机推荐
- train problem I (栈水题)
杭电1002http://acm.hdu.edu.cn/showproblem.php?pid=1022 Train Problem I Time Limit: 2000/1000 MS (Java/ ...
- 教你理解微信小程序的生命周期和运行原理
转自:http://blog.csdn.net/tsr106/article/details/53052879 写微信小程序,他的生命周期不能不知道,不知道小程序就会出现各种bug而无法解决.小助君 ...
- 使用vue-axios请求geoJson数据报错的问题
最近的项目用到了echarts一个带有散点地图的图表,按照正常jquery写法应该使用ajax请求geojson的数据动态去切换地图,就像下面这样 $.get('Js/map/' + cityData ...
- 【C#】数据库脚本生成工具(二)
年C#研发的数据库文档生成工具,给之后的工作带来了便利.近日,又针对该工具,用WinForm开发了数据库脚本生成工具-DbExcelToSQL. 下面数据库文档生成工具效果图: 感兴趣的朋友可以看下[ ...
- 安装Ubuntu16.04失败
原本安装的是Ubuntu14,但是在使用caffe时总是出错,所以干脆将Ubuntu从14升级到16,结果整出一堆麻烦.在解决这些麻烦的过程也学习了不少系统启动的细节.印证了那句话"如何没有 ...
- [国嵌攻略][077][Linux时间编程]
时间类型 Coordinated Universal Time(UTC):世界标准时间,也就是格林威治时间(Greenwich Mean Time, GMT). Calendar Time:日历时间, ...
- .22-浅析webpack源码之事件流compilation总览
呃,终于到了这地方-- newCompilation(params) { // ... this.applyPlugins("this-compilation", compilat ...
- 最近公司用到了lombok,感觉很不错的样子,所以上网搜了一些资料,总结了一下用法。
lombok作用:它提供了简单的注解形式来帮助我们简化消除一些必须有但显得很臃肿的Java代码,特别是相对于 POJO.缺点是使用lombok虽然能够省去手动创建setter和getter方法的麻烦, ...
- 邓_Excal
--------------------------------------------------------------------- 快速输入固定文字 有一些固定的词组,输入 1 个.2 个,貌 ...
- java—— finall 关键词
_ *{ margin: 0; padding: 0; } .on2{ margin: 10px 0; cursor: pointer; user-select: none; color: white ...