首页 > 其他分享 >CF522D Closest Equals

CF522D Closest Equals

时间:2022-09-19 10:35:26浏览次数:88  
标签:CF522D Closest int res Equals build 端点 INF

CF522D Closest Equals

题目大意

现在有一个序列 \(a_1, a_2, ..., a_n\) ,还有\(m\)个查询 \(l_j, r_j\) \((1 ≤ l_j ≤ r_j ≤n)\) 。对于每一个查询,请找出距离最近的两个元素 \(a_x\) 和 \(a_y\)$ (x ≠ y)$ ,并且满足以下条件:

\(l_j ≤ x, y ≤ r_j\);

\(a_x = a_y\)。

两个数字的距离是他们下标之差的绝对值 \(|x − y|\) 。

分析

只有询问,考虑离线。同时我们需要知道每个数它前一个数的位置,再次想到离线。

但是,按照我们经常的操作,我们是对扫到的当前点进行操作,但是如果此时我们对当前点插入与上一个点的距离,则无法保证左端点一定在我们的询问范围内。因此我们进行调整,因为我们右端点是卡死的,因此如果我们是向上一个点插入与当前点的距离,则能保证两个点都一定在询问范围内。

这里对我们有一定的启发式意义。如果询问要求的两个点都在询问范围内,右端点一定在范围内,则我们只需要将需要维护的值维护到左端点上。

AC_code

#include<bits/stdc++.h>
#define ios ios::sync_with_stdio(false); cin.tie(0), cout.tie(0)
using namespace std;

const int N = 5e5 + 10,INF = 0x3f3f3f3f;

struct Ask
{
    int l,r,id;
    bool operator<(const Ask& W) const
    {   
        return r<W.r;
    }
}ask[N];

struct Node
{
    int l,r,val;
}tr[N<<2];
unordered_map<int,int> pre;
int n,m,a[N],ans[N];

void build(int u,int l,int r)
{
    tr[u] = {l,r,INF};
    if(l==r) return ;
    int mid = l + r >> 1;
    build(u<<1,l,mid),build(u<<1|1,mid+1,r);
}

void pushup(int u)
{
    tr[u].val = min(tr[u<<1].val,tr[u<<1|1].val);
}

void modify(int u,int x,int k)
{
    if(tr[u].l==tr[u].r)
    {
        tr[u].val = k;
        return ;
    }
    int mid = tr[u].l + tr[u].r >> 1;
    if(x<=mid) modify(u<<1,x,k);
    else modify(u<<1|1,x,k);
    pushup(u);
}

int query(int u,int l,int r)
{
    if(l<=tr[u].l&&tr[u].r<=r) return tr[u].val;
    int mid = tr[u].l + tr[u].r >> 1;
    int res = INF;
    if(l<=mid) res = min(res,query(u<<1,l,r)) ;
    if(r>mid) res = min(res,query(u<<1|1,l,r));
    return res;
}

int main()
{
    ios;cin>>n>>m;
    for(int i=1;i<=n;i++) cin>>a[i];
    build(1,1,n);
    for(int i=0;i<m;i++)
    {
        int l,r;cin>>l>>r;
        ask[i] = {l,r,i};
    }
    sort(ask,ask+m);
    int now = 0;
    for(int i=0;i<m;i++)
    {
        int l = ask[i].l,r = ask[i].r,id = ask[i].id;
        while(now<r)
        {
            now++;
            if(pre.count(a[now])) modify(1,pre[a[now]],now-pre[a[now]]);
            pre[a[now]] = now;
        }
        int t = query(1,l,r);
        ans[id] = t==INF?-1:t;
    }
    for(int i=0;i<m;i++) cout<<ans[i]<<'\n';
    return 0;
}

标签:CF522D,Closest,int,res,Equals,build,端点,INF
From: https://www.cnblogs.com/aitejiu/p/16706844.html

相关文章

  • Java基础(四)—— HashCode和Equals
    正如标题所言,今天我们来讲讲hashCode和equals。或许有些人会奇怪了,这两个东西为什么要放在一起来讲呢?这是因为按照JDK规范:如果两个对象根据equals方法比较是相等的,那么调......
  • Collection集合中的 contains 和 remove 使用深入——要重写equals
    参考引用:http://t.csdn.cn/8z6sC 使用Collection集合中的contains,remove,removeall的时候,元素一定要重写equals方法,不然它里面的判断会容易出现“预期错误”。......
  • equals方法
    首先我们知道Java中Object类是所有类的父类,它里面定义了equals()方法:publicbooleanequals(Objectobj){return(this==obj);}可以看到是使用==来进行......
  • String ==和equals的区别
    public boolean equals(Object obj) {    return (this == obj);} Object中的equals()方法其实就是==,而String重写了equals()方法把它修改成比......
  • Lombok的使用 以及@EqualsAndHashCode
    @EqualsAndHashCode(of={"docId","travelDate"})其中,of选择指定的属性,构建生成equals方法与hashcode方法exclude排除制定属性lombok常用注释:1@Data//用于......
  • 【java面试题】 == 和 equals
    【java面试题】==和equals "=="比较的机制:==对比的是栈中的值基本数据类型是变量值,也就是inti=1;在栈中存放的是i=1,==比较的也是这个数值1引用类型是堆中......