Record a new line segment tree basic trick (it's really a pupil's trick)
To give you an arrangement of 1 to N, you need to judge whether there is a subsequence of 3 elements (which can be discontinuous) in the arrangement, so that the subsequence is an isochronous sequence. n<=3e5
Considering the related properties of the arithmetic sequence, for a 3-number arithmetic sequence, when a[i] is feasible as the intermediate term, if and only if there must be at least one K, so that the element a[i] - k is on its left and the element a[i] + k is on its right (for convenience, K here can be negative)
In the process of enumerating a[i] sequentially, we might as well mark the used a[i] as 1, mark the unused as zero, and then judge the k in all ranges
So you get a n2 of violence
It looks like this
//Talking to the moon #include <bits/stdc++.h> #define N 1000010 #define M 2000010 #define int long long #define int_edge int to[M],val[M],nxt[M],head[N],cnt=0; using namespace std; int used[10010],a[10010]; //void add_edge(int x,int y ){to[++cnt]=y;nxt[cnt]=head[x];head[x]=cnt;} int read(){ int fu=1,ret=0;char ch; for(;!isdigit(ch);ch=getchar())if(ch=='-')fu*=-1; for(;isdigit(ch);ch=getchar())ret=(ret<<1)+(ret<<3)+ch-'0'; return ret*fu; } signed main() { int n=read(),ans=0; for(int i=1;i<=n;i++)a[i]=read(); for(int i=1;i<=n;i++) { for(int j=1;a[i]-j>=1&&a[i]+j<=n;j++) if(used[a[i]-j]!=used[a[i]+j]){ans=1;break;} if(ans==1)break; used[a[i]]=1; } if(ans==1)puts("YES"); else puts("NO"); return 0; }
Next is the positive solution part
We find that there seems to be no optimization space for positive enumeration k, and the problem does not let us find k, so the positive difficulty is the opposite. We can consider the infeasible case as an intermediate term, that is, there is no k, so that the marks of a[i] + k and a[i] - k are the same
Isn't that a palindrome string
So our problem becomes to make a single point modification in the value range and judge whether the palindrome is added between areas
In fact, there is a very excellent simple Hash algorithm to judge the palindrome string without considering the modification
Consider the forward and reverse hashes once, and then judge whether the positive and negative Hash values of the query interval are equal
Then the Hash value can be added or subtracted
That is, you can add the hash value of a in bit 1 and the hash value of b in bit 2 to get the hash value of ab
Then the modification is simple. We can move the Hash to a segment tree (tree array can also be used)
Each leaf node stores the value after a single point hash
Then you can support single point modification and interval query
It should be noted that when merging, you need to multiply each bit by the corresponding hash base (such as the power of 131)
The same is true when querying
//Talking to the moon #include <bits/stdc++.h> #define N 300010 #define M 2000010 #define int unsigned long long #define int_edge int to[M],val[M],nxt[M],head[N],cnt=0; using namespace std; int a[N],h[N]; //void add_edge(int x,int y ){to[++cnt]=y;nxt[cnt]=head[x];head[x]=cnt;} int read(){ int fu=1,ret=0;char ch; for(;!isdigit(ch);ch=getchar())if(ch=='-')fu*=-1; for(;isdigit(ch);ch=getchar())ret=(ret<<1)+(ret<<3)+ch-'0'; return ret*fu; } int ls(int x){return x*2;} int rs(int x){return x*2+1;} struct Seg1{ int tr[N*4]; void update(int nw,int l,int r,int x){ if(l==r){ tr[nw]++; return; } int mid=(l+r)/2; if(x<=mid)update(ls(nw),l,mid,x); else update(rs(nw),mid+1,r,x); tr[nw]=tr[ls(nw)]*h[r-mid]+tr[rs(nw)]; } int query(int nw,int l,int r,int x,int y){ if(x<=l&&r<=y){ return tr[nw]*h[y-r]; } int mid=(l+r)/2,sum=0; if(x<=mid)sum+=query(ls(nw),l,mid,x,y); if(y>mid)sum+=query(rs(nw),mid+1,r,x,y); return sum; } }S1; struct Seg2{ int tr[N*4]; void update(int nw,int l,int r,int x){ if(l==r){ tr[nw]++; return; } int mid=(l+r)/2; if(x<=mid)update(ls(nw),l,mid,x); else update(rs(nw),mid+1,r,x); tr[nw]=tr[rs(nw)]*h[mid-l+1]+tr[ls(nw)]; } int query(int nw,int l,int r,int x,int y){ if(x<=l&&r<=y){ return tr[nw]*h[l-x]; } int mid=(l+r)/2,sum=0; if(x<=mid)sum+=query(ls(nw),l,mid,x,y); if(y>mid)sum+=query(rs(nw),mid+1,r,x,y); return sum; } }S2; signed main() { int n=read(),ans=0; h[0]=1;for(int i=1;i<=n;i++)h[i]=h[i-1]*131; for(int i=1;i<=n;i++) { a[i]=read(); int num=min(a[i]-1,n-a[i]),l=a[i]-num,r=a[i]+num; if(S1.query(1,1,n,l,r)!=S2.query(1,1,n,l,r)){ans=1;break;} S1.update(1,1,n,a[i]);S2.update(1,1,n,a[i]); } if(ans)puts("YES"); else puts("NO"); return 0; }