我们害怕把这道题题面搞得太无聊了,所以我们决定让这题超短。一个序列被称为是不无聊的,仅当它的每个连续子序列存在一个独一无二的数字,即每个子序列里至少存在一个数字只出现一次。给定一个整数序列,请你判断它是不是不无聊的。
Input
第一行一个正整数T,表示有T组数据。每组数据第一行一个正整数n,表示序列的长度,1 <= n <= 200000。接下来一行n个不超过10^9的非负整数,表示这个序列。
Output
对于每组数据输出一行,输出"non-boring"表示这个序列不无聊,输出"boring"表示这个序列无聊。
Sample Input
4
5
1 2 3 4 5
5
1 1 1 1 1
5
1 2 3 2 1
5
1 1 2 1 1
Sample Output
non-boring
boring
non-boring
boring
solution:
一类区间最大/最小问题,可以发现只要跨过某个位置的区间一定是合法的
那我们从这个位置两边分治就行了,然后还要保证复杂度,从两边向里找pos
code:
#include<bits/stdc++.h> #define lll long long #define rep(i,a,b) for(int i=a;i<=b;i++) #define all(x) (x).begin(),(x).end() using namespace std; const int N = 3e5+10; int n; int a[N]; lll ans=0; int L[N],R[N]; int pos[N]; vector<int> v; void dfs(int l,int r) { if(l>r)return ; int ll=l,rr=r; for(int i=l;i<=r;i++) { if(i&1) { if(L[ll]<l&&R[ll]>r) { ans += 1ll*(ll-l+1)*(r-ll+1); dfs(l,ll-1);dfs(ll+1,r);return ; } ll++; }else { if(L[rr]<l&&R[rr]>r) { ans += 1ll*(rr-l+1)*(r-rr+1); dfs(l,rr-1);dfs(rr+1,r);return ; } rr--; } } } int main() { int T;cin>>T; while(T--) { cin>>n;rep(i,1,n)scanf("%d",a+i); v.clear(); rep(i,1,n)v.push_back(a[i]); sort(all(v));v.erase(unique(all(v)),v.end()); rep(i,1,n)a[i]=lower_bound(all(v),a[i])-v.begin()+1; rep(i,1,n)pos[i]=0; rep(i,1,n) { if(!pos[a[i]])L[i]=0; else L[i]=pos[a[i]]+1; pos[a[i]]=i; } rep(i,1,n)pos[i]=0; for(int i=n;i;i--) { if(!pos[a[i]])R[i]=n+1; else R[i]=pos[a[i]]-1; pos[a[i]]=i; } ans=0;dfs(1,n); ans==1ll*n*(n+1)/2?puts("non-boring"): puts("boring"); } return 0; }