题解 | #小苯的回文询问#

https://ac.nowcoder.com/acm/contest/78292/F

主要思路是在遍历输入数组 a 的过程中,维护一个辅助数组 L 和一个 map 来记录特定元素最后出现的位置。具体的过程如下:
1. 首先,声明一个哈希表 map<int, int> mp 用来记录每个元素最后出现的位置。
2. 开始遍历数组 a,对于每个元素 a[i]:
  • 如果 mp 中已经存在元素 a[i],则表示之前已经出现过该元素,此时如果上一个位置mp[a[i]]小于当前位置的前一个位置(即不相邻,<=i-2),则更新 L[i] 为 max(L[i], mp[a[i]])。
  • 如果当前位置i>=3 并且 a[i] == a[i-2],则也更新 L[i] 为 i-2。
  • 更新 mp[a[i]] 为当前位置 i。
3. 在处理完整个数组后,得到了一个记录特定条件下位置的数组 L。
4. 接下来,对于每个查询区间 [l, r]:
  • 如果查询的右边界 r 大于2 并且 L[r] 大于等于左边界 l,则输出 "YES"。否则,输出 "NO"。

**##### - 由此我们总结出每当出现扫描区间的判断时,要注意在r更新的同时,的区间内部的值是否会影响l的判断

******

#include "bits/stdc++.h"
using namespace std;
typedef long long ll;
ll a[1000010];
ll L[1000010];
map<ll, ll> mp;

void solve(){
    ll n, q; cin>>n>>q;
    for(ll i=1; i<=n; i++){
        cin>>a[i]; L[i]=L[i-1];
        if(mp[a[i]]<i-1) L[i]=max(L[i], mp[a[i]]);  //更新左侧最右边满足条件的位置
        //a[i-1]==a[i]==a[i+1]需要特判,因为mp[a[i]]=i,所以不会进入上一行的if
        // 由此我们总结出每当出现扫描区间的判断时,要注意在r更新的同时,的区间内部的值是否会影响l的判断
        if(i>=3 && a[i]==a[i-2]) L[i]=i-2;
        mp[a[i]]=i;
    }
    while(q--){
        ll l, r; cin>>l>>r;
        if(L[r]>=l) cout<<"YES"<<endl;
        else cout<<"NO"<<endl;
    }
}

int main(){
    ios::sync_with_stdio(false);
    cin.tie(nullptr);
    cout.tie(nullptr);
    ll T=1;
    while(T--){
        solve();
    }
    return 0;
}

全部评论

相关推荐

星辰再现:裁员给校招生腾地方
点赞 评论 收藏
分享
05-22 12:44
已编辑
门头沟学院 golang
点赞 评论 收藏
分享
怎么起名字:早知道就不读书了,害得我送外卖还得扶眼镜
点赞 评论 收藏
分享
评论
4
2
分享

创作者周榜

更多
牛客网
牛客网在线编程
牛客网题解
牛客企业服务