BZOJ4527 : K-D-Sequence
先把所有数减去最小值,防止负数出现问题。
$d=0$,直接$O(n)$扫过去即可。
$d\neq 0$,首先通过双指针求出每个数作为右端点时往左可以延伸到哪里,中间任意两个数差值都是$d$的倍数且不重复。
然后从左往右枚举右端点$i$,那么左端点$j$需要满足:
$\lfloor\frac{\max(a[j]..a[i])}{d}\rfloor-\lfloor\frac{\min(a[j]..a[i])}{d}\rfloor+j\leq k+i$
用线段树+单调栈进行$\max$和$\min$的更新,并维护区间内这个式子的最小值,然后在线段树上二分即可。
时间复杂度$O(n\log n)$。
#include<cstdio>
#include<algorithm>
const int N=200010,M=524300;
int n,k,d,i,j,mi=~0U>>1,a[N],b[N],c[N],l[N],ap[N],cnt,q0[N],t0,q1[N],t1,t,L=1,R;
inline void read(int&a){
char c;bool f=0;a=0;
while(!((((c=getchar())>='0')&&(c<='9'))||(c=='-')));
if(c!='-')a=c-'0';else f=1;
while(((c=getchar())>='0')&&(c<='9'))(a*=10)+=c-'0';
if(f)a=-a;
}
inline void uans(int l,int r){if(r-l>R-L||r-l==R-L&&l<L)L=l,R=r;}
inline int lower(int x){
int l=1,r=n,mid,t;
while(l<=r)if(b[mid=(l+r)>>1]<=x)l=(t=mid)+1;else r=mid-1;
return t;
}
inline int abs(int x){return x>0?x:-x;}
int ma[M],mb[M],mc[M],mac[M],mbc[M],mabc[M],ta[M],tb[M];
inline int min(int a,int b){return a<b?a:b;}
inline void taga(int x,int p){ma[x]=ta[x]=p;mac[x]=mc[x]+p;mabc[x]=mbc[x]+p;}
inline void tagb(int x,int p){mb[x]=tb[x]=p;mbc[x]=mc[x]+p;mabc[x]=mac[x]+p;}
inline void pb(int x){
if(~ta[x])taga(x<<1,ta[x]),taga(x<<1|1,ta[x]),ta[x]=-1;
if(tb[x]<=0)tagb(x<<1,tb[x]),tagb(x<<1|1,tb[x]),tb[x]=1;
}
inline void up(int x){
ma[x]=min(ma[x<<1],ma[x<<1|1]);
mb[x]=min(mb[x<<1],mb[x<<1|1]);
mac[x]=min(mac[x<<1],mac[x<<1|1]);
mbc[x]=min(mbc[x<<1],mbc[x<<1|1]);
mabc[x]=min(mabc[x<<1],mabc[x<<1|1]);
}
void build(int x,int a,int b){
mc[x]=mac[x]=mbc[x]=mabc[x]=a;
ta[x]=-1,tb[x]=1;
if(a==b)return;
int mid=(a+b)>>1;
build(x<<1,a,mid),build(x<<1|1,mid+1,b);
}
void changea(int x,int a,int b,int c,int d,int p){
if(c<=a&&b<=d){taga(x,p);return;}
pb(x);
int mid=(a+b)>>1;
if(c<=mid)changea(x<<1,a,mid,c,d,p);
if(d>mid)changea(x<<1|1,mid+1,b,c,d,p);
up(x);
}
void changeb(int x,int a,int b,int c,int d,int p){
if(c<=a&&b<=d){tagb(x,p);return;}
pb(x);
int mid=(a+b)>>1;
if(c<=mid)changeb(x<<1,a,mid,c,d,p);
if(d>mid)changeb(x<<1|1,mid+1,b,c,d,p);
up(x);
}
void dfs(int x,int a,int b,int p){
if(a==b){t=a;return;}
pb(x);
int mid=(a+b)>>1;
if(mabc[x<<1]<=p)dfs(x<<1,a,mid,p);else dfs(x<<1|1,mid+1,b,p);
up(x);
}
void ask(int x,int a,int b,int c,int d,int p){
if(t)return;
if(c<=a&&b<=d){
if(mabc[x]<=p)dfs(x,a,b,p);
return;
}
pb(x);
int mid=(a+b)>>1;
if(c<=mid)ask(x<<1,a,mid,c,d,p);
if(d>mid)ask(x<<1|1,mid+1,b,c,d,p);
up(x);
}
int main(){
read(n),read(k),read(d);
for(i=1;i<=n;i++){
read(a[i]);
if(a[i]<mi)mi=a[i];
}
if(!d){
for(i=j=1;i<=n;i++){
if(a[i]!=a[j])j=i;
uans(j,i);
}
uans(j,n);
return printf("%d %d",L,R),0;
}
for(i=1;i<=n;i++)a[i]-=mi,b[i]=a[i];
for(std::sort(b+1,b+n+1),i=1;i<=n;i++)c[i]=lower(a[i]);
for(i=j=1;i<=n;i++){
if(!ap[c[i]])cnt++;ap[c[i]]++;
while(cnt<i-j+1){
ap[c[j]]--;if(!ap[c[j]])cnt--;
j++;
}
l[i]=j;
}
for(i=j=1;i<=n;i++){
if(abs(a[i]-a[i-1])%d)j=i;
if(l[i]<j)l[i]=j;
}
build(1,1,n);
for(i=1;i<=n;i++){
while(t0&&a[q0[t0]]<a[i])t0--;
changea(1,1,n,q0[t0]+1,i,a[i]/d);
q0[++t0]=i;
while(t1&&a[q1[t1]]>a[i])t1--;
changeb(1,1,n,q1[t1]+1,i,-a[i]/d);
q1[++t1]=i;
t=0,ask(1,1,n,l[i],i,k+i);
uans(t,i);
}
return printf("%d %d",L,R),0;
}
BZOJ4527 : K-D-Sequence的更多相关文章
- 【dfs】Sequence Decoding
Sequence Decoding 题目描述 The amino acids in proteins are classified into two types of elements, hydrop ...
- Gym 100703G---Game of numbers(DP)
题目链接 http://vjudge.net/contest/132391#problem/G Description standard input/outputStatements — It' s ...
- 转:Python获取随机数(中文)
下面介绍下random中常见的函数. 前提:需要导入random模块 >>>import random 1.random.random random.random() 用于生成一个0 ...
- Qt4--加密日记本(子例化QMainWindow文本加密解密)
近来刚学习Qt4编程,想找个实例练习练习,于是产生了一个想法,就是怎么样做一个文本加密,这样,自己保存的一些文档可以通过软件 生成加密文本,到时候要看的时候,通过自己的软件读取就可以.既然有想法了,那 ...
- python随机数
前提:需要导入random模块 >>>import random 1.random.random random.random()用于生成一个0到1的随机符小数: 0 <= n ...
- 关于python 模块导入
如何将自己写的库加入到python的库路径中: 首先查看python包含的库路径,步骤如下: a.打开python命令界面 b.import sys c.sys.path 1.在python安 ...
- 剑指Offer 23. 二叉搜索树的后序遍历序列 (二叉搜索树)
题目描述 输入一个整数数组,判断该数组是不是某二叉搜索树的后序遍历的结果.如果是则输出Yes,否则输出No.假设输入的数组的任意两个数字都互不相同. 题目地址 https://www.nowcoder ...
- 开发笔记:python与随机数(转)
这些天需要用到从一堆数中随机提取几个数,于是重新研究了下random模块. 下面介绍下random中常见的函数. 前提:需要导入random模块 >>>import random 1 ...
- Leetcode 413. Arithmetic Slice 算术序列切片(动态规划,暴力)
Leetcode 413. Arithmetic Slice 算术序列切片(动态规划,暴力) 题目描述 如果一个数组1.至少三个元素2.两两之间差值相同,那么这个数组就是算术序列 比如下面的数组都是算 ...
- python随机数的产生
导入 random模块 >>> import random 1. random.random random.random()用于生成一个0到1的随机浮点数: 0 <= n ...
随机推荐
- poj1988(并查集)
题目链接:http://poj.org/problem?id=1988 题意:有n个箱子,初始时每个箱子单独为一列: 接下来有p行输入,M, x, y 或者 C, x: 对于M,x,y:表示将x箱子所 ...
- 优化MyBatis配置文件中的配置
一.为实体类定义别名,简化sql映射xml文件中的引用 之前,我们在sql映射xml文件中的引用实体类时,需要写上实体类的全类名(包名+类名),如下: <!-- 创建用户(Create) --& ...
- Android高性能ORM数据库DBFlow入门
DBFlow,综合了 ActiveAndroid, Schematic, Ollie,Sprinkles 等库的优点.同时不是基于反射,所以性能也是非常高,效率紧跟greenDAO其后.基于注解,使用 ...
- 四、优化及调试--网站优化--Yahoo军规下
21.根据域名划分页面内容 很显然, 是最大限度地实现平行下载 22.尽量减少iframe的个数 考虑即使内容为空,加载也需要时间,会阻止页面加载,没有语意,注意iframe相对于其他DOM元素高出1 ...
- 使用dynatrace+showslow进行前端性能测试
1.背景 应用的性能测试与优化目前主要停留在服务器端的反馈,而对于前端性能标准的研究与测试相对比较空白,缺乏统一的标准与工具.众所周知,浏览器html组件的下载及渲染性能直接影响最终的用户体验,目前应 ...
- 与你相遇好幸运,Sail.js其他字段查询
query: function (req, res) { var par = req.query; for(var key in par){ var options = {}; ...
- 【JAVA网络流之URL】
一.URL URL对象可以认为是URLConnection对象+Socket对象. Java.lang.Object |-Java.net.URL 常用构造方法: URL(String spec) ...
- 详细的JavaScript事件使用指南
事件流 事件流描述的是从页面中接收事件的顺序,IE和Netscape提出来差不多完全相反的事件流的概念,IE事件流是事件冒泡流,Netscape事件流是事件捕获流. 事件冒泡 IE的事件流叫做事 ...
- js onclick="return test()"事件返回值,对有些事件,会影响默认动作的执行。如:onclick和onsubmit
onclick="return test()"事件返回值,对有些事件,会影响默认动作的执行.如:onclick和onsubmit <body> <!--事件返回值 ...
- [Qcon] 百姓网开发总结
拿到的PPT看了之后,发现给出的很简洁,但每个步骤用处却非常有用,我们一个个来分析: 1. 集中开发环境,这些方法看似简单,但是都是很实用的方法,在我开发中看的出来,SVN无分支就能解决我现有部门的部 ...