Codeforces452F(MemSQL Start[c]UP 2.0)[Permutation]--线段树+Hash
2017-10-12 18:53
549 查看
【题目链接】
codeforces452F
【题目大意】
定义一个长度为 n 的数列为反等差数列,当且仅当
是一个 1∼n 的排列
不存在任意一个长度大于等于3的子序列是一个等差数列
比如, 1,3,4,2是一个反等差数列,而 1,5,2,4,3不满足条件
现在,给你一个 1∼n 的排列,你需要判断它是不是一个反等差数列
【解题报告】
对于一个数x(1<x<n),令p=min(x-1,n-x),易知如果给出的排列满足题意,那么[x-p,x-1]和[x+1,x+p]两个区间里的数的位置要么都在x的左边,要么都在x的右边。所以用线段树维护并用Hash数组记录就可以解决了。
codeforces452F
【题目大意】
定义一个长度为 n 的数列为反等差数列,当且仅当
是一个 1∼n 的排列
不存在任意一个长度大于等于3的子序列是一个等差数列
比如, 1,3,4,2是一个反等差数列,而 1,5,2,4,3不满足条件
现在,给你一个 1∼n 的排列,你需要判断它是不是一个反等差数列
【解题报告】
对于一个数x(1<x<n),令p=min(x-1,n-x),易知如果给出的排列满足题意,那么[x-p,x-1]和[x+1,x+p]两个区间里的数的位置要么都在x的左边,要么都在x的右边。所以用线段树维护并用Hash数组记录就可以解决了。
#include<cstdio> #include<cstring> #include<algorithm> using namespace std; typedef unsigned int uint; const int maxn=300005,maxm=1200005; int n,las; uint ans,sed[maxn],len[maxm],la[maxm],ra[maxm]; inline int Read() { int res=0; char ch=getchar(); while (ch<'0'||ch>'9') ch=getchar(); while (ch>='0'&&ch<='9') res=res*10+ch-48,ch=getchar(); return res; } void Build(int d,int L,int R) { if (L==R) {len[d]=1; return;} int mid=(R-L>>1)+L; Build(d<<1,L,mid); Build((d<<1)+1,mid+1,R); len[d]=len[d<<1]+len[(d<<1)+1]; } void Pushup(int d) { la[d]=la[d<<1]+la[(d<<1)+1]*sed[len[d<<1]]; ra[d]=ra[d<<1]*sed[len[(d<<1)+1]]+ra[(d<<1)+1]; } void Insert(int d,int where,int l,int r) { if (l==r) {la[d]=ra[d]=1; return;} int mid=(r-l>>1)+l; if (where<=mid) Insert(d<<1,where,l,mid); else Insert((d<<1)+1,where,mid+1,r); Pushup(d); } void Ask_la(int d,int l,int r,int x,int y) { if (x>r||l>y) return; if (x<=l&&r<=y) {ans+=la[d]*sed[las]; las+=len[d]; return;} int mid=(r-l>>1)+l; Ask_la(d<<1,l,mid,x,y); Ask_la((d<<1)+1,mid+1,r,x,y); } void Ask_ra(int d,int l,int r,int x,int y) { if (x>r||l>y) return; if (x<=l&&r<=y) {ans+=ra[d]*sed[las]; las+=len[d]; return;} int mid=(r-l>>1)+l; Ask_ra((d<<1)+1,mid+1,r,x,y); Ask_ra(d<<1,l,mid,x,y); } int main() { freopen("F.in","r",stdin); freopen("F.out","w",stdout); n=Read(); sed[0]=1; Build(1,1,n); for (int i=1; i<=n; i++) sed[i]=sed[i-1]*2333; for (int i=1; i<=n; i++) { int x=Read(),k=min(x-1,n-x); Insert(1,x,1,n); if (!k) continue; ans=0; las=0; Ask_la(1,1,n,x+1,x+k); uint sum=ans; ans=0; las=0; Ask_ra(1,1,n,x-k,x-1); if (ans!=sum) {printf("YES\n"); return 0;} } printf("NO\n"); return 0; }
相关文章推荐
- [Hash] Codeforces 452F MemSQL Start[c]UP 2.0 - Round 1 F. Permutation
- MemSQL Start[c]UP 2.0 - Round 2 A
- MemSQL Start[c]UP 2.0 - Round 1
- MemSQL Start[c]UP 2.0 - Round 2 - Online Round A,B,C
- CF memsql Start[c]UP 2.0 B
- MemSQL Start[c]UP 2.0 - Round 1
- CF memsql Start[c]UP 2.0 A
- MemSQL Start[c]UP 2.0 - Round 1 D. Washer, Dryer, FoldercO
- MemSQL Start[c]UP 2.0 - Round 1A(构造)
- MemSQL Start[c]UP 2.0 - Round 1 .A
- MemSQL Start[c]UP 2.0 - Round 1 B. 4-point polyline (线段的 枚举)
- MemSQL Start[c]UP 2.0 - Round 2 - Online Round
- MemSQL Start[c]UP 2.0 - Round 2 - Online Round(数学:高精度)
- codeforces MemSQL Start[c]UP 2.0 - Round 1 A. Eevee
- codeforces MemSQL Start[c]UP 2.0 - Round 1 B. 4-point polyline
- codeforces memsql Start[c]UP 2.0 C. Magic Trick
- MemSQL Start[c]UP 2.0 - Round 1
- MemSQL Start[c]UP 2.0 - Round 1(无聊练手B题)
- MemSQL Start[c]UP 2.0 - Round 2 - Online Round 题解
- Codeforces Round #437 (Div. 2, based on MemSQL Start[c]UP 3.0 - Round 2) C - Ordering Pizza