Professor GukiZ was playing with arrays again and accidentally discovered new function, which he called GukiZiana. For given array a, indexed with integers from 1 to n, and number y, GukiZiana(a, y) represents maximum value of j - i, such that aj = ai = y. If there is no y as an element in a, then GukiZiana(a, y) is equal to - 1. GukiZ also prepared a problem for you. This time, you have two types of queries:
- First type has form 1 l r x and asks you to increase values of all ai such that l ≤ i ≤ r by the non-negative integer x.
- Second type has form 2 y and asks you to find value of GukiZiana(a, y).
For each query of type 2, print the answer and make GukiZ happy!
The first line contains two integers n, q (1 ≤ n ≤ 5 * 105, 1 ≤ q ≤ 5 * 104), size of array a, and the number of queries.
The second line contains n integers a1, a2, ... an (1 ≤ ai ≤ 109), forming an array a.
Each of next q lines contain either four or two numbers, as described in statement:
If line starts with 1, then the query looks like 1 l r x (1 ≤ l ≤ r ≤ n, 0 ≤ x ≤ 109), first type query.
If line starts with 2, then th query looks like 2 y (1 ≤ y ≤ 109), second type query.
For each query of type 2, print the value of GukiZiana(a, y), for y value for that query.
4 3
1 2 3 4
1 1 2 1
1 1 1 1
2 3
2
2 3
1 2
1 2 2 1
2 3
2 4
0
-1
思路:分块,map超时,MLE,vector+二分即可;
#include<bits/stdc++.h> using namespace std; #define ll long long #define pi (4*atan(1.0)) #define eps 1e-14 #define bug(x,y) cout<<"bug"<<x<<" "<<y<<endl; #define bug(x) cout<<"xxx "<<x<<endl; const int N=5e5+10,M=1e6+10,inf=2e9+10,mod=6; const ll INF=1e18+10; ll a[N],add[N]; int n,q,ka,pos[N]; vector<pair<ll,int> >vec[710]; int cmp(pair<ll,int> a,pair<ll,int> b) { if(a.first==b.first) return a.second<b.second; return a.first<b.first; } int ansl,ansr; void brute(int l,int r,int pos) { vec[pos].clear(); for(int i=l; i<=r; i++) vec[pos].push_back(make_pair(a[i],i)); sort(vec[pos].begin(),vec[pos].end(),cmp); } void brutef(int l,int r,int pos,ll x) { for(int i=l; i<=r; i++) { if(add[pos]+a[i]==x) { ansl=min(ansl,i); ansr=max(ansr,i); } } } void update(int l,int r,ll x) { if(pos[l]==pos[r]) { for(int i=l;i<=r;i++) a[i]+=x; brute((pos[l]-1)*ka+1,pos[l]*ka,pos[l]); return; } for(int i=pos[l]+1; i<=pos[r]-1; i++) add[i]+=x; for(int i=l; i<=min(r,pos[l]*ka); i++) a[i]+=x; brute((pos[l]-1)*ka+1,pos[l]*ka,pos[l]); for(int i=max(l,(pos[r]-1)*ka+1); i<=r; i++) a[i]+=x; if(pos[r]<=n/ka) brute((pos[r]-1)*ka+1,pos[r]*ka,pos[r]); } void slove(ll x) { ansl=n+1; ansr=0; for(int i=1; i<=n/ka; i++) { int l1=0,l2=0,l=-1; int r1=ka-1,r2=ka-1,r=-1; while(l1<=r1) { int mid=(l1+r1)>>1; if(vec[i][mid].first<x-add[i]) l1=mid+1; else if(vec[i][mid].first==x-add[i]) { l=mid; r1=mid-1; } else r1=mid-1; } while(l2<=r2) { int mid=(l2+r2)>>1; if(vec[i][mid].first<x-add[i]) l2=mid+1; else if(vec[i][mid].first==x-add[i]) { r=mid; l2=mid+1; } else r2=mid-1; } if(l!=-1) { ansl=min(ansl,vec[i][l].second); ansr=max(ansr,vec[i][r].second); } } brutef((n/ka)*ka+1,n,n/ka+1,x); //cout<<ansr<<" "<<ansl<<endl; if(ansl==n+1) puts("-1"); else printf("%d ",ansr-ansl); } int main() { scanf("%d%d",&n,&q); for(int i=1; i<=n; i++) scanf("%lld",&a[i]); ka=sqrt(n); for(int i=1; i<=n; i++) pos[i]=(i-1)/ka+1; for(int i=1; i<=n/ka; i++) brute(ka*(i-1)+1,ka*i,i); while(q--) { int flag,l,r; ll x; scanf("%d",&flag); if(flag==1) { scanf("%d%d%lld",&l,&r,&x); update(l,r,x); } else { scanf("%lld",&x); slove(x); } } return 0; }