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:
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
题意:
维护一个长为n的序列,支持两种操作:1.将[l,r]内的每个数增加x,2.对于给定的y,输出满足a[j]=a[i]=y的j-i的最大值,无解输出-1.
分析:
按sqrt(n)的大小分块,对于每一个块,维护块内元素的一个有序序列,对于操作1,如果整个块被修改操作覆盖,由于块内元素相对大小不变,只需打一个标记,如果某个块中有部分元素被修改,则暴力重构整个块,询问时对每个块分别查询,最后统计全局最优值。复杂度O(nlogn+qsqrt(n)logn)。
代码:
#include<cstdio> #include<cstdlib> #include<cstring> #include<cmath> #include<iostream> #include<algorithm> #include<vector> using namespace std; typedef long long ll; ll a[500005]; vector<pair<ll,int> >s[805]; vector<int>res; vector<pair<ll,int> >::iterator itr; ll tag[805]; int main() { int n,q; scanf("%d%d",&n,&q); int b_s=(int)sqrt(n); for(int i=0;i<n;i++) { scanf("%I64d",&a[i]); } int loc=-1; for(int i=0;i<n;i++) { if(i%b_s==0)loc++; s[loc].push_back(make_pair(a[i],i)); } for(int i=0;i<=loc;i++) { sort(s[i].begin(),s[i].end()); } int op,l,r; ll x,y; while(q--) { scanf("%d",&op); if(op==1) { scanf("%d%d%I64d",&l,&r,&x); l--,r--; int bl=l/b_s; int br=r/b_s; for(int i=bl+1;i<br;i++) { tag[i]+=x; } for(int i=0;i<s[bl].size();i++) { s[bl][i].first+=tag[bl]; if(s[bl][i].second>=l && s[bl][i].second<=r) s[bl][i].first+=x; } sort(s[bl].begin(),s[bl].end()); tag[bl]=0; if(br>bl) { for(int i=0;i<s[br].size();i++) { s[br][i].first+=tag[br]; if(s[br][i].second>=l && s[br][i].second<=r) s[br][i].first+=x; } sort(s[br].begin(),s[br].end()); tag[br]=0; } } else { scanf("%I64d",&y); res.clear(); for(int i=0;i<=loc;i++) { itr=lower_bound(s[i].begin(),s[i].end(),make_pair(y-tag[i],0)); if(itr!=s[i].end() && (*itr).first==y-tag[i])res.push_back((*itr).second); itr=lower_bound(s[i].begin(),s[i].end(),make_pair(y-tag[i]+1,0)); if(itr!=s[i].begin()) { itr--; if((*itr).first==y-tag[i])res.push_back((*itr).second); } } if(res.empty())printf("-1\n"); else { sort(res.begin(),res.end()); printf("%d\n",res[res.size()-1]-res[0]); } } } return 0; }