[TC-FindingFriends]Finding Friends
题目大意:
给定一个长度为$n(n\le10^5)$的数列$A(A_i\le10^9)$,求最小的$k$满足存在一个长度至少为$m(m\le n)$的子串,对于串中的每一个数$A_i$,都至少存在一个$A_j(i\ne j)$满足$|A_i-A_j|<k$。
思路:
二分答案$k$,对于每次求出每个元素$A_i$左边离$A_i$最近的满足$|A_i-A_j|<k$的$left[i]=j$,同理求出每个元素$A_j$右边离$A_i$最近的满足$|A_i-A_j|<k$的$right[i]=j$。
考虑分治,判断区间$[l,r]$是否是满足条件的字串。
若$r-l+1<m$则显然不满足条件。
在$[l,r]$中找到一个下标$p$满足$left[p]<l$且$right[p]>r$,则若这样的$p$存在,则包含$p$的区间一定不满足条件,递归处理$[l,p)$和$(p,r]$。若找不到这样的$p$,则该区间满足条件,$k$为合法的答案。
寻找$p$时,如果不是直接for而是从两端同时往里寻找,设找到的$p$两端的区间长度分别是$a$和$b$,则递归的复杂度是$O(n\log n)$(递推式$T(n)=T(a)+T(b)+\min(a,b)$)。而$left$和$right$的预处理可以用线段树实现,总的时间复杂度是$O(n\log^2 n)$。
#include<vector>
#include<cstdio>
#include<climits>
#include<algorithm>
class FindingFriends {
private:
using int64=long long;
static constexpr int N=1e5+;
int n,m,lim,arr[N],tmp[N],left[N],right[N];
class SegmentTree {
#define _left <<1
#define _right <<1|1
private:
int max[N<<],min[N<<];
void push_up(const int &p) {
max[p]=std::max(max[p _left],max[p _right]);
min[p]=std::min(min[p _left],min[p _right]);
}
public:
void reset() {
std::fill(&max[],&max[N<<],INT_MIN);
std::fill(&min[],&min[N<<],INT_MAX);
}
void modify(const int &p,const int &b,const int &e,const int &x,const int &y) {
if(b==e) {
max[p]=std::max(max[p],y);
min[p]=std::min(min[p],y);
return;
}
const int mid=(b+e)>>;
if(x<=mid) modify(p _left,b,mid,x,y);
if(x>mid) modify(p _right,mid+,e,x,y);
push_up(p);
}
int qmax(const int &p,const int &b,const int &e,const int &l,const int &r) {
if(b==l&&e==r) return max[p];
const int mid=(b+e)>>;
int ret=INT_MIN;
if(l<=mid) ret=std::max(ret,qmax(p _left,b,mid,l,std::min(mid,r)));
if(r>mid) ret=std::max(ret,qmax(p _right,mid+,e,std::max(mid+,l),r));
return ret;
}
int qmin(const int &p,const int &b,const int &e,const int &l,const int &r) {
if(b==l&&e==r) return min[p];
const int mid=(b+e)>>;
int ret=INT_MAX;
if(l<=mid) ret=std::min(ret,qmin(p _left,b,mid,l,std::min(mid,r)));
if(r>mid) ret=std::min(ret,qmin(p _right,mid+,e,std::max(mid+,l),r));
return ret;
}
#undef _left
#undef _right
};
SegmentTree t;
bool check(const int &l,const int &r) {
if(r-l+<m) return false;
int pos=-;
for(register int i=;l+i<=r-i;i++) {
if(left[l+i]<l&&right[l+i]>r) {
pos=l+i;
break;
}
if(left[r-i]<l&&right[r-i]>r) {
pos=r-i;
break;
}
}
return pos==-||check(l,pos-)||check(pos+,r);
}
int getlow(const int &x) const {
return std::upper_bound(&tmp[],&tmp[tmp[]]+,x-)-tmp;
}
int getup(const int &x) const {
return std::lower_bound(&tmp[],&tmp[tmp[]]+,x+)--tmp;
}
bool check(const int &k) {
t.reset();
for(register int i=;i<=n;i++) {
left[i]=t.qmax(,,tmp[],std::max(getlow(tmp[arr[i]]-k),),std::min(getup(tmp[arr[i]]+k),tmp[]));
t.modify(,,tmp[],arr[i],i);
}
t.reset();
for(register int i=n;i>=;i--) {
right[i]=t.qmin(,,tmp[],std::max(getlow(tmp[arr[i]]-k),),std::min(getup(tmp[arr[i]]+k),tmp[]));
t.modify(,,tmp[],arr[i],i);
}
return check(,n);
}
public:
int shortestDistance(const int &nn,const std::vector<int> &init,const int &a,const int &b,const int &c,const int &d,const int &mm) {
n=nn,m=mm;
for(register unsigned i=;i<init.size();i++) arr[i+]=init[i];
for(register int i=init.size();i<n;i++) {
arr[i+]=(((int64)arr[i]*a%d+(int64)b*i%d)%d+c)%d;
}
lim=*std::max_element(&arr[],&arr[n]+);
std::copy(&arr[],&arr[n]+,&tmp[]);
std::sort(&tmp[],&tmp[n]+);
tmp[]=std::unique(&tmp[],&tmp[n]+)-&tmp[];
for(register int i=;i<=n;i++) {
arr[i]=std::lower_bound(&tmp[],&tmp[tmp[]]+,arr[i])-tmp;
}
int l=,r=lim;
while(l<=r) {
const int mid=(l+r)/;
if(check(mid)) {
r=mid-;
} else {
l=mid+;
}
}
return r+;
}
};
[TC-FindingFriends]Finding Friends的更多相关文章
- POJ_3740 Easy Finding ——精确覆盖问题,DLX模版
Easy Finding Time Limit: 1000MS Memory Limit: 65536K Total Submissions: 18790 Accepted: 5184 Des ...
- hdu-5992 Finding Hotels(kd-tree)
题目链接: Finding Hotels Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 102400/102400 K (Java/ ...
- H TC並沒有成為下一個摩托羅拉或諾基亞。
關於2014年第四季度,H T C在三季度財報說明中提到,“年度旗艦H T CO ne(M 8)與中端機型H T C D esire系列在競爭日趨激烈的智能手機市場保持穩定的銷售,市占率有所提升,延續 ...
- [转] Finding the Best Programmer's Font
原文 Finding the Best Programmer's Font
- TC(Total Commander)文件管理神器
TC文件管理神器 Total Commander是一个会显著提高文件操作效率的工具,而文件操作是应用计算机最基本的功夫,也是伴随一生的操作.因此花一点时间学习,而会受益一世. Total Comman ...
- Linux TC基于CBQ队列的流量管理范例
参考了TC的很多文档,自己也整理了一篇配置记录.在实际使用过程中效果还不错,在此分享给大家以备参考.环境:局域网规模不是很大40多台机器. NAT共享上网(内网:eth0 外网:eth2)CBQ是通过 ...
- Linux TC流量控制HOWTO中文版
<本文摘自Linux的高级路由和流量控制HOWTO中文版 第9章节>网人郭工进行再次编译: 利用队列,我们可以控制数据发送的方式.记住我们只能对发送数据进行控制(或称为整形).其实,我们无 ...
- LOJ Finding LCM(math)
1215 - Finding LCM Time Limit: 2 second(s) Memory Limit: 32 MB LCM is an abbreviation used for Least ...
- 蒟蒻修养之tc蓝名计划
开一个新坑......(听说tc是智商高的人才能玩的QAQ显然我是被屠的... 1 [645DIV2]这个能说是裸模拟吗... 弃坑= =做了一些题感觉没必要放上来了= =等div1先吧....... ...
- 验证码识别 edge enhancement - 轮廓增强 region finding - 区域查找
Computer Science An Overview _J. Glenn Brookshear _11th Edition The task of understanding general im ...
随机推荐
- python3创建目录
感觉python3最好用的创建目录函数是os.makedirs,它可以设置在多级目录不存在时自动创建,已经存在也不抛出异常. import os os.makedirs('hello/hello1/h ...
- oracle与mysql的group by语句
之所以去纠那么细节的问题,是因为之前有过一个这样的场景: 有个同学,给了一条数据库的语句给我,问,为啥这样子的语句在oracle语句下执行不了. 1 select * from xx where xx ...
- rsync安装使用详解
rsync是类unix系统下的数据镜像备份工具,从软件的命名上就可以看出来了——remote sync.它的特性如下: 可以镜像保存整个目录树和文件系统. 可以很容易做到保持原来文件的权限.时间.软硬 ...
- css属性选择器应用
代码: <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3. ...
- Spring学习--集合属性
Spring 中可以通过一组内置的 xml 标签(例如: <list> , <set> 或 <map>) 来配置集合属性. 配置java.util.Set 需要使用 ...
- Topcoder SRM 608 div1 题解
Easy(300pts): 题目大意:有n个盒子,一共有S个苹果,每个盒子有多少个苹果不知道,但是知道每个盒子的苹果下限和上限.现在要至少选择X个苹果,问如果要保证无论如何都能获得至少X个苹果,至少需 ...
- mybatis基本流程、jdbc连接、ps:附mybatis(乐观锁)实现
一.前言 Mybatis和Hibernate一样,是一个优秀的持久层框架.已经说过很多次了,原生的jdbc操作存在大量的重复性代码(如注册驱动,创建连接,创建statement,结果集检测等).框架的 ...
- 51nod 1060 最复杂的数
把一个数的约数个数定义为该数的复杂程度,给出一个n,求1-n中复杂程度最高的那个数. 例如:12的约数为:1 2 3 4 6 12,共6个数,所以12的复杂程度是6.如果有多个数复杂度相等,输出最 ...
- Python小程序之购物车
需求: 用户入口: 1.商品信息放在文件中,从文件中读取 2.已购商品,余额记录,第一要输入起始金额,以后不需要二次输入 商家入口: 2.可以添加商品,修改商品价格 # Author:Lee Siri ...
- boost::function的简单实现
前言 boost::function和boost:bind是一对强大的利器.相信用过的童鞋多少有些体会. 虽然平时在用boost::function,但是用的时候心中总会一些不安,因为不知道它是怎么实 ...