MemSQL Start[c]UP 2.0 - Round 1 F - Permutation 思维+线段树维护hash值

F - Permutation

思路:对于当前的值x, 只需要知道x + k, x - k这两个值是否出现在其左右两侧,又因为每个值只有一个,

所以可以转换成,x+k, x-k在到x所在位置的时候是否都出现,或者都不出现,即出现情况相等,我们可以

用线段树维护hash值的方式来判断所有x+k,  x-k的出现情况是否都一样。

#include<bits/stdc++.h>
#define LL long long
#define fi first
#define se second
#define mk make_pair
#define PII pair<int, int>
#define PLI pair<LL, int>
#define ull unsigned long long
using namespace std;

const int N = 3e5 + 7;
const int inf = 0x3f3f3f3f;
const LL INF = 0x3f3f3f3f3f3f3f3f;
const int mod = 1e9 + 7;
const double eps = 1e-8;

int n;
ull Pow[N];
struct segmentTree {
#define lson l,mid,rt<<1
#define rson mid+1,r,rt<<1|1
    struct info1 {
        ull hs; int len;
        info1 operator + (const info1 &rhs) {
            return info1{hs+rhs.hs*Pow[len], len+rhs.len};
        }
    } a[N<<2];
    struct info2 {
        ull hs; int len;
        info2 operator + (const info2 &rhs) {
            return info2{rhs.hs+hs*Pow[rhs.len], len+rhs.len};
        }
    } b[N<<2];
    void build(int l, int r, int rt) {
        if(l == r) {
            a[rt] = info1{0, 1};
            b[rt] = info2{0, 1};
            return;
        }
        int mid = l + r >> 1;
        build(lson); build(rson);
        a[rt] = a[rt<<1] + a[rt<<1|1];
        b[rt] = b[rt<<1] + b[rt<<1|1];
    }
    void update(int p, int l, int r, int rt) {
        if(l == r) {
            a[rt] = info1{1, 1};
            b[rt] = info2{1, 1};
            return ;
        }
        int mid = l + r >> 1;
        if(p <= mid) update(p, lson);
        else update(p, rson);
        a[rt] = a[rt<<1] + a[rt<<1|1];
        b[rt] = b[rt<<1] + b[rt<<1|1];
    }
    info1 querya(int L, int R, int l, int r, int rt) {
        if(l >= L && r <= R) return a[rt];
        int mid = l + r >> 1;
        if(R <= mid) return querya(L, R, lson);
        else if(L > mid) return querya(L, R, rson);
        else return querya(L, R, lson) + querya(L, R, rson);
    }
    info2 queryb(int L, int R, int l, int r, int rt) {
        if(l >= L && r <= R) return b[rt];
        int mid = l + r >> 1;
        if(R <= mid) return queryb(L, R, lson);
        else if(L > mid) return queryb(L, R, rson);
        else return queryb(L, R, lson) + queryb(L, R, rson);
    }
} seg;

int main() {
    for(int i=Pow[0]=1; i < N; i++) Pow[i]=Pow[i-1]*131;
    scanf("%d", &n);
    seg.build(1, n, 1);
    bool flag = false;
    for(int i = 1; i <= n; i++) {
        int x; scanf("%d", &x);
        int len = min(x-1, n-x);
        if(len && seg.querya(x-len, x-1, 1, n, 1).hs != seg.queryb(x+1, x+len, 1, n, 1).hs)
            flag = true;
        seg.update(x, 1, n, 1);
    }
    if(flag) puts("YES");
    else puts("NO");
    return 0;
}

/*
*/

猜你喜欢

转载自www.cnblogs.com/CJLHY/p/9895664.html
今日推荐