首先,容易得到判断一个子串为“good k-d sequence”的方法:

  • 子串中没有重复元素,且所有元素模d相等。
  • 记mx为除以d的最大值,mn为除以d的最小值,则\(mx-mn<=r-l+k\)。

然后,我们对于每一段极大的元素同模的子串,处理\(d=1\)的情况。

显然,我们需要枚举一个端点。这里,我们从大到小枚举左端点。(当然,从小到大枚举右端点也是可行的)

我们使用单调栈和线段树,可以维护每个位置\(mx-mn\)的值。然后,因为对于每一个位置,\(r\)是固定的,所以我们把\(r\)移到左边。即有不等式\(mx-mn-r<=k-l\)。

然后,我们需要确定最右边的\(mx-mn-r<=k-l\)的元素位置,这个线段树上二分就可以了。

最后还有两个细节:

  • 为避免出现重复元素,线段树上二分时有限制。
  • 特判\(d=0\)的情况。

时间复杂度\(O(nlogn)\)。

#include <bits/stdc++.h>
using namespace std;
const int BAS = 1e9, N = 200010;
struct node {
int mn,tag;
inline void operator += (int x) {
mn += x;
tag += x;
}
inline void reset() {
mn = tag = 0;
}
} t[N << 2];
void push_down(int x) {
t[x<<1] += t[x].tag;
t[x<<1|1] += t[x].tag;
t[x].tag = 0;
}
void push_up(int x) {
if (t[x].tag) push_down(x);
t[x].mn = min(t[x<<1].mn,t[x<<1|1].mn);
}
void modify(int x,int l,int r,int v,int lp,int rp) {
if (lp > r || rp < l) return;
if (lp >= l && rp <= r)
return (void)(t[x] += v);
int mid = (lp + rp) >> 1;
modify(x<<1,l,r,v,lp,mid);
modify(x<<1|1,l,r,v,mid+1,rp);
push_up(x);
}
int dfs(int x,int lim,int v,int lp,int rp) {
if (t[x].mn > v) return -1;
if (lp == rp) return lp;
push_down(x);
int mid = (lp + rp) >> 1;
if (t[x<<1|1].mn <= v && mid + 1 <= lim) {
int res = dfs(x<<1|1,lim,v,mid+1,rp);
if (~res) return res;
}
return dfs(x<<1,lim,v,lp,mid);
}
int n,k,d,arr[N],len;
map<int,int> mp;
int tmp[N];
struct data_sta {
int l,r,val;
inline bool operator < (const data_sta& x) const {
return val < x.val;
}
} st[2][N];
int top[2];
struct data_ans {
int l,r;
inline bool operator < (const data_ans& x) const {
return r - l + 1 != x.r - x.l + 1 ? \
r - l + 1 > x.r - x.l + 1 : l < x.l;
}
};
data_ans solve() {
mp.clear();
data_sta tp;
data_ans res = (data_ans) {len,-1};
int cur = len, rec;
top[0] = top[1] = 0;
for (int i = len ; i >= 1 ; -- i) {
if (mp[tmp[i]]) cur = min(cur,mp[tmp[i]] - 1);
mp[tmp[i]] = i;
tp = (data_sta) {i,i,tmp[i]};
while (top[0] && st[0][top[0]].val < tp.val) {
modify(1,st[0][top[0]].l,st[0][top[0]].r,-st[0][top[0]].val,1,len);
tp.r = st[0][top[0]--].r;
}
st[0][++top[0]] = tp;
modify(1,tp.l,tp.r,tp.val,1,len);
tp = (data_sta) {i,i,tmp[i]};
while (top[1] && st[1][top[1]].val > tp.val) {
modify(1,st[1][top[1]].l,st[1][top[1]].r,st[1][top[1]].val,1,len);
tp.r = st[1][top[1]--].r;
}
st[1][++top[1]] = tp;
modify(1,tp.l,tp.r,-tp.val,1,len);
modify(1,i,i,-i,1,len);
rec = dfs(1,cur,k - i,1,len);
if (~rec) res = min(res,(data_ans) {i,rec});
}
for (int i = 1 ; i <= (len << 2) ; ++ i)
t[i].reset();
return res;
}
int special_solve() {
int res = 0, p = -1;
for (int i = 1, j; i <= n ; i += j) {
j = 1;
while (arr[i+j] == arr[i] && i + j <= n) ++ j;
if (res < j) res = j, p = i;
}
printf("%d %d\n",p,p + res - 1);
return 0;
}
int main() {
scanf("%d%d%d",&n,&k,&d);
for (int i = 1 ; i <= n ; ++ i)
scanf("%d",&arr[i]), arr[i] += BAS ;
if (d == 0) return special_solve();
data_ans res = (data_ans) {1,1}, tp;
for (int i = 1, j ; i <= n ; i += j) {
j = 1;
while (arr[i+j] % d == arr[i] % d && i + j <= n)
++ j;
len = j;
for (int s = 0 ; s < j ; ++ s)
tmp[s+1] = arr[i+s] / d;
tp = solve();
tp.l += i-1, tp.r += i-1;
res = min(res,tp);
}
printf("%d %d\n",res.l,res.r);
return 0;
}

小结:这样一类题目大概就是要怼着式子简化问题。

【做题】CF239E. k-d-sequence——线段树的更多相关文章

  1. 2016暑假多校联合---Rikka with Sequence (线段树)

    2016暑假多校联合---Rikka with Sequence (线段树) Problem Description As we know, Rikka is poor at math. Yuta i ...

  2. Wow! Such Sequence!(线段树4893)

    Wow! Such Sequence! Time Limit: 10000/5000 MS (Java/Others) Memory Limit: 65536/65536 K (Java/Others ...

  3. HDU 6047 Maximum Sequence(线段树)

    题目网址:http://acm.hdu.edu.cn/showproblem.php?pid=6047 题目: Maximum Sequence Time Limit: 4000/2000 MS (J ...

  4. Codeforces 438D The Child and Sequence - 线段树

    At the children's day, the child came to Picks's house, and messed his house up. Picks was angry at ...

  5. ZOJ 4100 浙江省第16届大学生程序设计竞赛 A题 Vertices in the Pocket 线段树+并查集

    正赛的时候完全没看这个题,事后winterzz告诉我他想出来的解法. 首先题意是给出n个点,m次操作. 操作有一种是连接两个点,另一种是求此时再为这个图连k条边,最少和最多能有几个联通块. 最少的求法 ...

  6. Codeforces 486E LIS of Sequence(线段树+LIS)

    题目链接:Codeforces 486E LIS of Sequence 题目大意:给定一个数组.如今要确定每一个位置上的数属于哪一种类型. 解题思路:先求出每一个位置选的情况下的最长LIS,由于開始 ...

  7. K - Japan(线段树)

    Japan plans to welcome the ACM ICPC World Finals and a lot of roads must be built for the venue. Jap ...

  8. 【BZOJ】3038: 上帝造题的七分钟2(线段树+暴力)

    http://www.lydsy.com:808/JudgeOnline/problem.php?id=3038 这题我就有得吐槽了,先是线段树更新写错,然后不知哪没pushup导致te,精度问题sq ...

  9. Codeforces Round #250 (Div. 1) D. The Child and Sequence 线段树 区间取摸

    D. The Child and Sequence Time Limit: 20 Sec Memory Limit: 256 MB 题目连接 http://codeforces.com/contest ...

  10. codevs2492上帝造题的七分钟 2(线段树)

    /* 区间修改 区间查询 可以用线段树搞 但是一般的标记下放对这个题好像不合适 只能改叶子 然后更新父亲(虽然跑的有点慢) 小优化:如果某个点是1 就不用再开方了 所以搞一个f[i]标记 i 这个点还 ...

随机推荐

  1. Rpgmakermv(16) YEP MainmenuManager

    ---------------------------------------------------------------------------------------------------- ...

  2. sql server2000中使用convert来取得datetime数据类型样式(转)

    日期数据格式的处理,两个示例: CONVERT(varchar(16), 时间一, 20) 结果:2007-02-01 08:02/*时间一般为getdate()函数或数据表里的字段*/ CONVER ...

  3. C# & ASP.NET Core 入门官方资料汇总

    借助给公司实习生培训事宜,整理了一些微软官方的适合新同学入门的资料,这里分享一下: 工具: Visual Studio 2017 Community 版本下载地址:https://www.visual ...

  4. 准备dbcp2-2.1.1和pool2-2.4.2 、commons-dbcp-1.4jar包

    下载地址:https://pan.baidu.com/s/1gtcW36Lz6Yt-j9WlTu31Pw

  5. 20165215 2017-2018-2 《Java程序设计》第7周学习总结

    20165215 2017-2018-2 <Java程序设计>第七周学习总结 教材学习内容总结 chapter11 下载安装MySQL服务器 启动MySQL数据库服务器 在bin子目录中, ...

  6. 【JavaScript 6连载】二、函数(工厂模式)

    <!DOCTYPE html><html lang="en"><head><meta charset="UTF-8"& ...

  7. django -- 修改admin 密码问题

    1.python manage.py shell 2.from django.contrib.auth.models import User 3.user=User.objects.get(usern ...

  8. jQuery的ajaxFileUpload上传插件——刷新一次才能再次调用触发change

    这个问题并不是由change事件失效造成的,而是ajaxFileUpload插件造成的,它会把原来的file元素替换成新的file元素,所以之前绑定的change事件就失效了. 查了一些资料,有些朋友 ...

  9. 怎样从外网访问内网微服务Microservices?

    本地部署了一个微服务,只能在局域网内访问,怎样从外网也能访问到本地的微服务呢?本文将介绍具体的实现步骤. 准备工作 部署并启动微服务程序 默认部署的微服务端口是8088. 实现步骤 下载并解压hole ...

  10. OpenGL: 实现立体显示

    https://blog.csdn.net/augusdi/article/details/19922295 立体显示原理:设没有立体显示的模型视图矩阵ModelView为Mv,投影矩阵为Mp,则.物 ...