bzoj2124 equal difference subsequence

The meaning of the question: give you a permutation of 1~n, ask the order (not required to be consecutive) to take three numbers, is it possible to be an arithmetic sequence? n<=1W.

 

Standard range:

 1 #include<bits/stdc++.h>
 2 using namespace std;
 3 const int N=10005;
 4 const int can=31;
 5 const int mod=20010531;
 6 typedef long long ll;
 7 int T,bit[N],Bit[N],pw[N],a[N],n;
 8 int lowbit(int x){return x&(-x);}
 9 void add(int x){int y=x;while (x<=n) bit[x]=((ll)bit[x]+pw[x-y])%mod,x+=lowbit(x);}
10 int sum(int x){int res=0,y=x;while (x) res=((ll)res+(ll)bit[x]*pw[y-x]%mod)%mod,x-=lowbit(x);return res;}
11 void Add(int x){int y=x;while (x) Bit[x]=((ll)Bit[x]+pw[y-x])%mod,x-=lowbit(x);}
12 int Sum(int x){int res=0,y=x;while (x<=n) res=((ll)res+(ll)Bit[x]*pw[x-y]%mod)%mod,x+=lowbit(x);return res;}
13 int qry(int x,int l){return ((ll)sum(x)-(ll)sum(x-l)*pw[l]%mod+mod)%mod;}
14 int Qry(int x,int l){return ((ll)Sum(x)-(ll)Sum(x+l)*pw[l]%mod+mod)%mod;}
15 int main()
16 {
17     pw[0]=1;
18     for (int i=1;i<N;i++) pw[i]=(ll)pw[i-1]*can%mod;
19     scanf("%d",&T);
20     while (T--)
21     {
22         scanf("%d",&n);memset(bit,0,sizeof(bit));memset(Bit,0,sizeof(Bit));
23         for (int i=1;i<=n;i++) scanf("%d",&a[i]);
24         int fl=0;
25         for (int i=1;i<=n;i++) 
26         {
27             int len=min(a[i]-1,n-a[i]);
28             if (a[i]!=1&&a[i]!=n&&qry(a[i]-1,len)!=Qry(a[i]+1,len)) {fl=1;puts("Y");break;}
29             add(a[i]);Add(a[i]);
30         }
31         if (!fl) puts("N");
32     }
33     return 0;
34 }

 

Error-prone points: 1. Pay attention to the boundary judgment, a[i]!=1 and a[i]!=n, and judge the palindrome and pay attention to the length of the palindrome on the left and right sides of the palindrome.

2. The len step cannot be skipped directly on the tree array (different from the bit dichotomy), and the prefix and subtraction need to be used.

 

Solution: tree array + hash

Enumerate the middle number x of the arithmetic sequence, that is, ask whether a number that appears before the number + the number that appears after it is possible = 2*x.

Sweep sequentially with a tag to indicate whether a certain number appears. The above conditions are satisfied if and only if there is a y that does not exceed the boundary, such that tag[xy]!=tag[x+y] (one appears, one does not appear), then Yes can be directly judged. Consider the case of No as a palindrome. Use hash to compare palindrome, tree array maintains the prefix and suffix sum of hash values ​​to support dynamic modification and interval query. The time complexity is O(nlogn).

Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=324798913&siteId=291194637