MemSQL Start[c]UP 2.0 - Round 1 F - Permutation 思维+线段树维护hash值
Posted notnight
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了MemSQL Start[c]UP 2.0 - Round 1 F - Permutation 思维+线段树维护hash值相关的知识,希望对你有一定的参考价值。
思路:对于当前的值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; } /* */
以上是关于MemSQL Start[c]UP 2.0 - Round 1 F - Permutation 思维+线段树维护hash值的主要内容,如果未能解决你的问题,请参考以下文章
Codeforces Round #437 (Div. 2, based on MemSQL Start[c]UP 3.0 - Round 2)
Codeforces Round #437 (Div. 2, based on MemSQL Start[c]UP 3.0 - Round 2)
Codeforces Round #437 (Div. 2, based on MemSQL Start[c]UP 3.0 - Round 2)
Codeforces Round #437 (Div. 2, based on MemSQL Start[c]UP 3.0 - Round 2)
Codeforces Round #437 (Div. 2, based on MemSQL Start[c]UP 3.0 - Round 2) E
Codeforces Round #437 (Div. 2, based on MemSQL Start[c]UP 3.0 - Round 2) C. Ordering Pizza