Non-boring seqences

原文链接: http://www.cnblogs.com/rign/p/11297973.html
#include 
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]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;
}

确定整个区间是否每个子区间都有一个数字只出现一次,利用分治

注意优化:1.记录每个数字左右侧再次出现的位置,O(1)check

2.分治时,每次左右侧同时检查,这样防止出现每次都检查到最后再分治

启发式分治、折半分治

转载于:https://www.cnblogs.com/rign/p/11297973.html

你可能感兴趣的:(Non-boring seqences)