[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 ...
随机推荐
- python构建一个项目
二.实验步骤 2.1 实验准备 我们的实验项目名为 factorial. $ mkdir factorial $ cd factorial/ 2.2 主代码 我们给将要创建的 Python 模块取名为 ...
- input 只允许输入数字
onkeyup='this.value=this.value.replace(/[^0-9\-]/gi,"")'
- linux crontab执行shell脚本中包含相对路径的问题
实例一 test.sh文件 echo `date`>test.log 配置crontab 设置 */1 * * * * sh /data/test.sh 在/data/目录下,未找到test.l ...
- 查找算法总结Java实现
之前对查找算法做的一些简单总结与实现: 查找算法时间复杂度: 1.二分查找的实现(待补充) public class Test { //循环实现二分查找 public static int binar ...
- python 实现定时循环触发某个方法
直接贴上代码 import threading def sayhello(): print "hello world" global t #Notice: use global v ...
- PL/SQL 08 异常 exception
--PL/SQL错误 编译时 运行时 --运行时的出错处理 EXCEPTION --异常处理块DECLARE …BEGIN …EXCEPTION WHEN OTHERS THEN handle ...
- 对象存储 - Swift 原理 及 Swift+keystone+dashboard 架构搭建
1. 原理介绍 Swift 架构.原理及功能: http://www.cnblogs.com/sammyliu/p/4955241.html 总结的很详细也很全面,受益匪浅,感谢分享. 2. keys ...
- ipad/iphone中的前端调试
需要在ipad上调试代码, 经过一番搜索(多在google搜到的), 稍微整理下 : ). 1. Settings -> Safari -> Advanced/Developer -> ...
- Spring boot 文件路径读取异常
在开发代码中,有一段需要获取resources目录下的一个配置文件(这里写作test.xml). 这段代码在ide中没有任何问题,但是一打成jar包发布到线上,这段代码就会报找不到对应文件的错误. 按 ...
- 在Js或者cess后加版本号 防止浏览器缓存
在Js或者cess后加版本号 防止浏览器缓存 客户端浏览器会缓存css或js文件,从而减少加载次数,减少流量,提高网页的访问速度.为了使得每次修改js或者css能生效,可以通过改变版本号来使得客户端浏 ...