Non-boring seqences

#include <bits/stdc++.h>
using namespace std;
#define fore(i,_a,_b) for(int i=(int)(_a);i<=(int)(_b);i++)
#define forb(i,_a,_b) for(int i=(int)(_a);i>=(int)(_b);i--)
#define fir first
#define sec second
#define SZ(a) (int)(a).size()
#define pb push_back
#define all(c) (c).begin(), (c).end()
#define endl '\n'
typedef long long ll;
typedef unsigned long long ull;
typedef pair<int,int> pii;
const int INF=0x3f3f3f3f;
map<int,int>mp;
const int N=(int)2e5+5;
int pre[N],nex[N];
int a[N];

bool is_unique(int p,int l,int r){
    if(pre[p]<l && nex[p]>r) return true;
    return false;
}

bool check(int l,int r){
    if(l>=r) return true;
    int mid=(r-l+1)>>1;
    fore(i,1,mid+1){
        int lpos=l+i-1;
        if(is_unique(lpos,l,r)){
            return check(l,lpos-1)&check(lpos+1,r);
        }
        int rpos=r-i+1;
        if(is_unique(rpos,l,r)){
            return check(l,rpos-1)&check(rpos+1,r);
        }
    }
    return false;
}

int main(){
    ios::sync_with_stdio(0);
    cin.tie(0);
    cout.tie(0);
    int T;cin>>T;
    while(T--){
        int n;cin>>n;
        fore(i,1,n) cin>>a[i];
        mp.clear();
        fore(i,1,n){
            if(!mp.count(a[i])) pre[i]=-1;
            else pre[i]=mp[a[i]];
            mp[a[i]]=i;
        }
        mp.clear();
        forb(i,n,1){
            if(!mp.count(a[i])) nex[i]=n+1;
            else nex[i]=mp[a[i]];
            mp[a[i]]=i;
        }
        if(check(1,n)) cout<<"non-boring"<<endl;
        else cout<<"boring"<<endl;
    }
    return 0;
}

Determine whether the entire interval for each sub-section has a number appears only once, use divide and conquer

Optimization Note: digital recording position of each of the left and right side appears again, O (1) check

2. partition, while checking each right and left side, thus preventing re-checked at each occurrence are the last partition

Heuristic divide and conquer, binary divide and conquer

Guess you like

Origin www.cnblogs.com/rign/p/11297973.html