CF765F Souvenirs
\[首先考虑离线,固定R,考虑加入R会对前面的答案造成怎样的影响
\\
然后,规定只统计(i<j且a[i]>a[j])
\\
找到当前位置能更新的最近的位置,记为now
\\
在now前面的nowp,必须要(a[nowp]-a[i])<|a[nowp]-a[now]|=>(a[nowp])<\dfrac{a[i]+a[now]}{2}
\\
这样每次值域都会减半
\]
#include<bits/stdc++.h>
#define INF 1e9
#define ls Tree[p].lc
#define rs Tree[p].rc
using namespace std;
const int MAXN=6e5+5;
struct Segment{
int lc,rc;
int date;
}Tree[MAXN*4];
void push_up(int p)
{
Tree[p].date=max(Tree[ls].date,Tree[rs].date);
}
int root;
int cnt_Tree;
int New()
{
++cnt_Tree;
Tree[cnt_Tree].date=0;
Tree[cnt_Tree].lc=0;
Tree[cnt_Tree].rc=0;
return cnt_Tree;
}
void Update(int &p,int l,int r,int x,int k)
{
if(!p)
{
p=New();
}
if(l==r)
{
Tree[p].date=max(Tree[p].date,k);
return;
}
int mid=(l+r)>>1;
if(x<=mid){
Update(ls,l,mid,x,k);
}
else
{
Update(rs,mid+1,r,x,k);
}
push_up(p);
}
int Query(int p,int l,int r,int ql,int qr)
{
if(!p)
{
return 0;
}
if(l>=ql&&r<=qr)
{
return Tree[p].date;
}
int mid=(l+r)>>1;
int res=0;
if(ql<=mid)
{
res=max(res,Query(ls,l,mid,ql,qr));
}
if(qr>mid)
{
res=max(res,Query(rs,mid+1,r,ql,qr));
}
return res;
}
int Bit[MAXN];
int n;
int lowbit(int x){
return x&(-x);
}
void update(int k,int x)
{
for(int i=k;i>=1;i-=lowbit(i))
{
Bit[i]=min(Bit[i],x);
}
return;
}
int Min(int k)
{
int res=0x3f3f3f3f;
for(int i=k;i<=n;i+=lowbit(i))
{
res=min(res,Bit[i]);
}
return res;
}
int q;
int a[MAXN];
int l,r;
vector<pair<int,int> >ruery[MAXN];
int ans[MAXN];
void Work()
{
cnt_Tree=0;
root=0;
memset(Bit,0x3f,sizeof(Bit));
for(int i=1;i<=n;i++)
{
int now=Query(root,1,INF,a[i]+1,INF);
while(now)
{
// printf("%d\n",now);
update(now,a[now]-a[i]);
//now=Query(root,1,INF,)
int nexr=(a[now]+a[i]);
if(nexr%2==0){
nexr=nexr/2-1;
}
else
{
nexr=(nexr-1)/2;
}
now=Query(root,1,INF,a[i]+1,nexr);
}
Update(root,1,INF,a[i],i);
for(int j=0;j<ruery[i].size();j++)
{
ans[ruery[i][j].second]=min(ans[ruery[i][j].second],Min(ruery[i][j].first));
}
}
}
int main()
{
scanf("%d",&n);
scanf("%d",&q);
for(int i=1;i<=n;i++)
{
scanf("%d",&a[i]);
}
for(int i=1;i<=q;i++)
{
scanf("%d %d",&l,&r);
ruery[r].push_back(make_pair(l,i));
ans[i]=0x3f3f3f3f;
}
Work();
for(int i=1;i<=n;i++)
{
a[i]=INF-a[i];
}
Work();
for(int i=1;i<=q;i++)
{
printf("%d\n",ans[i]);
}
}
//$$
//首先考虑离线,固定R,考虑加入R会对前面的答案造成怎样的影响
//\\
//然后,规定只统计(i<j且a[i]>a[j])
//\\
//找到当前位置能更新的最近的位置,记为now
//\\
//在now前面的nowp,必须要(a[nowp]-a[i])<|a[nowp]-a[now]|=>(a[nowp])<\dfrac{a[i]+a[now]}{2}
//\\
//这样每次值域都会减半
//$$