社区讨论

(玄关)站外题求助

学术版参与者 10已保存回复 20

讨论操作

快速查看讨论及其快照的属性,并进行相关操作。

当前回复
20 条
当前快照
1 份
快照标识符
@mhz49rm1
此快照首次捕获于
2025/11/15 01:13
3 个月前
此快照最后确认于
2025/11/16 14:20
3 个月前
查看原帖
一个序列被称为是不无聊的,仅当它的每个连续子序列存在一个独一无二的数字,即每个子序列里至少存在一个数字只出现一次。
给定一个整数序列,请你判断它是不是不无聊的。
思路:CDQ 分治。
CPP
#include<bits/stdc++.h>
#define int long long
using namespace std;
int n,a[200005],flag;
int tt[200005],lst[200005],nxt[200005];
int temp[200005];
void cdq(int l,int r){
    if (l==r)return;
    int mid=(l+r)/2;
    cdq(l,mid);
    if (flag==0)return;
    cdq(mid+1,r);
    if (flag==0)return;
    set<int> s;map<int,int> sm;
    for (int i=mid;i>=l;i--){
        sm[a[i]]++;
        if (sm[a[i]]==1){
            s.insert(nxt[i]);
        }
        else if (sm[a[i]]==2){
            s.erase(nxt[nxt[i]]);
        }
        auto itt=s.lower_bound(r+1);
        if (itt!=s.end())temp[i]=1e18;
        else temp[i]=*(--itt);
    }
    s.clear();sm.clear();
    for (int i=mid+1;i<=r;i++){
        sm[a[i]]++;
        if (sm[a[i]]==1){
            s.insert(lst[i]);
        }
        else if (sm[a[i]]==2){
            s.erase(lst[lst[i]]);
        }
        auto it=s.lower_bound(l);
        if (it!=s.begin()){
            temp[i]=-1e18;
        }
        else temp[i]=*it;
    }
    for (int i=r-1;i>mid;i--){
        temp[i]=max(temp[i],temp[i+1]);
    }
    for (int i=l;i<=mid;i++){
        if (temp[i]==1e18)continue;
        if (temp[temp[i]]>=i){
            flag=0;return;
        }
    }
}
int lsh[200005];
void solve(){
    cin>>n;
    for (int i=1;i<=n;i++){
        cin>>a[i];
        lsh[i]=a[i];
    }
    sort(lsh+1,lsh+1+n);
    int kk=unique(lsh+1,lsh+1+n)-lsh-1;
    for (int i=1;i<=n;i++){
        a[i]=lower_bound(lsh+1,lsh+1+kk,a[i])-lsh;
    }
    for (int i=1;i<=n;i++)tt[i]=0;
    for (int i=1;i<=n;i++){
        lst[i]=tt[a[i]];
        tt[a[i]]=i;
    }
    for (int i=1;i<=n;i++)tt[i]=n+1;
    for (int i=n;i>=1;i--){
        nxt[i]=tt[a[i]];
        tt[a[i]]=i;
    }
    flag=1;
    cdq(1,n);
    if (flag)cout<<"non-boring\n";
    else cout<<"boring\n";
}
signed main(){
    int t;cin>>t;
    while (t--)solve();
    return 0;
}
TEST 1 在 non-boring(不无聊)的数据输出了 boring(无聊)。
目前还没有搓出小 Hack。

回复

20 条回复,欢迎继续交流。

正在加载回复...