社区讨论
(玄关)站外题求助
学术版参与者 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 条回复,欢迎继续交流。
正在加载回复...