bzoj4865: [Ynoi2017]由乃运椰子
在线询问区间众数,传统的分块(记录块间众数和每个权值的出现次数)做法被卡空间(分块用的空间是O(块数*(块数+权值种类数))),因此考虑去掉出现次数较小的数,只用分块维护出现次数较大的数。设K为分界线,用原来的分块维护原序列中出现次数>K的数组成的部分,而出现次数<=K的数,可以通过记录一个数前面第1~K个相同的数的位置,用线段树维护,线段树查询时利用单调性单次询问可以做到$O(k+logn)$,不会成为瓶颈。
当K取$O(n^{1/4})$时,时间复杂度仍是$O(q\sqrt{n})$,空间复杂度为$O(n^{5/4})$
#include<bits/stdc++.h>
char buf[],*ptr=buf+;
int g(){
if(ptr-buf==)fread(buf,,,stdin)[buf]=,ptr=buf;
return *ptr++;
}
int __(){
int x=,c=g();
while(c<)c=g();
while(c>)x=x*+c-,c=g();
return x;
}
int _(){
if(ptr-buf>)return __();
int x=,c=*ptr++;
while(c<)c=*ptr++;
while(c>)x=x*+c-,c=*ptr++;
return x;
}
typedef unsigned short u16;
int n,m;
int v0[],vs[],B,v1[],vp1=;
u16 bc[][],ws[],t[],rid[],bb[][],pv[],pw[];
int ls[],rs[];
u16 tr[][];
int max(int a,int b){return a>b?a:b;}
int get(int l,int r){
int p=;
for(int a=l+,b=r+;b-a!=&&p<;a>>=,b>>=){
if(~a&)while(p<&&tr[a^][p]>=l)++p;
if(b&)while(p<&&tr[b^][p]>=l)++p;
}
return p+;
}
int main(){
n=_();m=_();
for(int i=;i<=n;++i)vs[i]=v0[i]=_();
std::sort(vs+,vs+n+);
for(int i=;i<=n;++i)v0[i]=std::lower_bound(vs+,vs+n+,v0[i])-vs;
for(int i=;i<=n;++i){
int x=v0[i];
pv[i]=pw[x];
pw[x]=i;
for(int j=,z=pv[i];j<;++j)tr[i+][j]=z,z=pv[z];
}
for(int i=;i;--i){
int a=i<<,b=a^;
for(int j=;j<;++j)tr[i][j]=max(tr[a][j],tr[b][j]);
}
for(int i=;i<=n;++i)++t[v0[i]];
int idp=;
for(int i=;i<=n;++i)if(t[i]>)rid[i]=++idp; for(int i=;i<=n;++i)if(rid[v0[i]]){
v1[++vp1]=rid[v0[i]];
v0[i]=vp1;
}else v0[i]=v0[i-];
for(int i=;i<=n;++i)t[i]=;
n=vp1;
for(B=;n/B>;++B);
for(int l=,r=B,c=;l<=n;l+=B,r+=B,++c){
if(r>n)r=n;
ls[c]=l;rs[c]=r;
for(int i=ls[c];i<=rs[c];++i)ws[i]=c;
for(int b=c;b;--b){
bb[c][b]=bb[c][b+];
for(int i=ls[b];i<=rs[b];++i)if(v1[i]){
int x=++bc[c][v1[i]];
if(x>bc[c][bb[c][b]])bb[c][b]=v1[i];
}
}
}
int la=;
while(m--){
int L=_()^la,R=_()^la;
int a0=get(L,R);
L=v0[L-]+;R=v0[R];
int l=ws[L],r=ws[R];
if(a0<)la=a0;
else if(r-l<=){
la=a0;
for(int i=L;i<=R;++i){
int x=v1[i];
if(x&&++t[x]>la)la=t[x];
}
for(int i=L;i<=R;++i)--t[v1[i]];
}else{
--r,++l;
int mx=bb[r][l];
u16*s1=bc[r],*s2=bc[l-];
for(int i=rs[l-];i>=L;--i){
int x=v1[i];
int t1=++t[x]+s1[x]-s2[x];
if(t1>t[mx]+s1[mx]-s2[mx])mx=x;
}
for(int i=ls[r+];i<=R;++i){
int x=v1[i];
int t1=++t[x]+s1[x]-s2[x];
if(t1>t[mx]+s1[mx]-s2[mx])mx=x;
}
la=max(a0,t[mx]+bc[r][mx]-bc[l-][mx]);
for(int i=rs[l-];i>=L;--i)--t[v1[i]];
for(int i=ls[r+];i<=R;++i)--t[v1[i]];
}
printf("-%d\n",la);
}
return ;
}
bzoj4865: [Ynoi2017]由乃运椰子的更多相关文章
- bzoj 3597: [Scoi2014]方伯伯运椰子 0/1分数规划
3597: [Scoi2014]方伯伯运椰子 Time Limit: 30 Sec Memory Limit: 64 MBSubmit: 144 Solved: 78[Submit][Status ...
- bzoj 3597: [Scoi2014]方伯伯运椰子 [01分数规划 消圈定理 spfa负环]
3597: [Scoi2014]方伯伯运椰子 题意: from mhy12345 给你一个满流网络,对于每一条边,压缩容量1 需要费用ai,扩展容量1 需要bi, 当前容量上限ci,每单位通过该边花费 ...
- bzoj3597[Scoi2014]方伯伯运椰子 01分数规划+spfa判负环
3597: [Scoi2014]方伯伯运椰子 Time Limit: 30 Sec Memory Limit: 64 MBSubmit: 594 Solved: 360[Submit][Statu ...
- 「SCOI2014」方伯伯运椰子 解题报告
「SCOI2014」方伯伯运椰子 可以看出是分数规划 然后我们可以看出其实只需要改变1的流量就可以了,因为每次改变要保证流量守恒,必须流成一个环,在正负性确定的情况下,变几次是无所谓的. 然后按照套路 ...
- 【BZOJ3597】方伯伯运椰子(分数规划,网络流)
[BZOJ3597]方伯伯运椰子(分数规划,网络流) 题解 给定了一个满流的费用流模型 如果要修改一条边,那么就必须满足流量平衡 也就是会修改一条某两点之间的路径上的所有边 同时还有另外一条路径会进行 ...
- 3597: [Scoi2014]方伯伯运椰子[分数规划]
3597: [Scoi2014]方伯伯运椰子 Time Limit: 30 Sec Memory Limit: 64 MB Submit: 404 Solved: 249 [Submit][Sta ...
- bzoj 3597: [Scoi2014]方伯伯运椰子
Description Input 第一行包含二个整数N,M 接下来M行代表M条边,表示这个交通网络 每行六个整数,表示Ui,Vi,Ai,Bi,Ci,Di 接下来一行包含一条边,表示连接起点的边 Ou ...
- bzoj 3597 [Scoi2014] 方伯伯运椰子 - 费用流 - 二分答案
题目传送门 传送门 题目大意 给定一个费用流,每条边有一个初始流量$c_i$和单位流量费用$d_i$,增加一条边的1单位的流量需要花费$b_i$的代价而减少一条边的1单位的流量需要花费$a_i$的代价 ...
- 2019.03.28 bzoj3597: [Scoi2014]方伯伯运椰子(01分数规划)
传送门 题意咕咕咕有点麻烦不想写 思路: 考虑加了多少一定要压缩多少,这样可以改造边. 于是可以通过分数规划+spfaspfaspfa解决. 代码: #include<bits/stdc++.h ...
随机推荐
- 在使用 interface 声明一个接口时,只可以使用那个修饰符修饰该接口?
这是一个看似简单其实挺有深意的题目,答案应该大多数人都知道是什么,不过原理和原因相比很少有人仔细研究过.对于本题,我有三点说明,希望看到这个评论的人能从这三点中看到你以前没注意到的东西: ①接口的声 ...
- ios-邮箱正则表达式判断
- (void)loadData { NSMutableArray *array = [NSMutableArray arrayWithCapacity:10]; if ([self.title is ...
- PureComponent的作用及一些使用陷阱
默认渲染行为的问题 在React Component的生命周期中,有一个shouldComponentUpdate方法.这个方法默认返回值是true. 这意味着就算没有改变组件的props或者stat ...
- C++中的抽象类
一.抽象类学习笔记 1.virtual修饰函数(虚函数)后面加=0就称为一个纯虚函数,一个类中只要有纯虚函数那么它就是一个抽象类.抽象类不能用来实例化对象,是用来给他的派生类定义好这些框架的,给使用这 ...
- System.Collections 学习
public interface IEnumerator { object Current { get; } bool MoveNext(); void Reset(); } public inter ...
- Sql server日期函数用法
SQL日期函数 SQL日期函数中的类型码可以为0,1,2,3,4,5,6,7,8,9,10,11,12,13,14 ,20,21,22,23,24,25,100,101,102,103,104,105 ...
- adb command
- JavaScript编码风格
最近在看前端大牛Nicbolas C.Zakas的<编写可维护的JavaScript代码>一书.觉得里面的很多知识点都写的很好,所以,就写篇博文,总结一下吧!编码规范对于程序设计来说是很重 ...
- MongoDB索引的种类与使用
一:索引的种类 1:_id索引:是绝大多数集合默认建立的索引,对于每个插入的数据,MongoDB都会自动生成一条唯一的_id字段2:单键索引: 1.单键索引是最普通的索引 2.与_id索引不同,单键索 ...
- js 字符串转对象
使用eval var test = '{ colkey: "col", colsinfo: "NameList" }' var obj2 = eval(&quo ...