思路:这题可以说是写的吐血了,只因为没有考虑到没有1操作,直接2操作询问的情况,分块之后就要rubuild ,不然直接二分查找vector内数据不是有序的就会混乱!!
Code:
#include <bits/stdc++.h>
#define LL long long
#define INF 0x3f3f3f3f
using namespace std;
const int AX = 1e5+66;
int b[AX];
int n , q ;
LL add[AX];
int len ;
struct Node{
int x , id;
}a[AX];
std::vector<Node> s[AX];
bool cmp(const Node &a,const Node &b){
if( a.x == b.x ) return a.id < b.id;
return a.x < b.x;
}
void rebuild( int t ){
s[t].clear();
for( int i = ( t - 1 ) * len + 1 ; i <= min( n , t * len ) ; i++ ){
s[t].push_back(a[i]);
}
sort( s[t].begin() , s[t].end() , cmp );
}
void update( int l , int r , int c ){
for( int i = l ; i <= min( r , b[l] * len ) ; i++ ){
a[i].x += c;
}
rebuild( b[l] );
if( b[l] != b[r] ){
for( int i = ( b[r] - 1 ) * len + 1 ; i <= r ; i++ ){
a[i].x += c;
}
rebuild( b[r] );
}
for( int i = b[l] + 1 ; i < b[r] ; i++ ){
add[i] += c;
}
}
int query( int v ){
int li = INF;
int ri = -INF;
for( int i = 1 ; i <= b[n] ; i++ ){
Node tmp ;
tmp.x = v - add[i];
tmp.id = 0;
vector<Node>::iterator it = lower_bound( s[i].begin() , s[i].end() , tmp , cmp );
if( it == s[i].end() ) continue;
while( it != s[i].end() ){
if( (*it).x == tmp.x ){
li = min( li , (*it).id );
ri = max( ri , (*it).id );
}else break;
it++;
}
}
if( li == INF || ri == -INF )
return -1;
return ri - li;
}
int main(){
scanf("%d%d",&n,&q);
for( int i = 1 ; i <= n ; i++ ){
scanf("%d",&a[i].x);
a[i].id = i;
}
len = sqrt(n);
for( int i = 1 ; i <= n ; i++ ){
b[i] = (( i - 1 ) / len) + 1 ;
s[b[i]].push_back( a[i] );
}
for( int i = 1 ; i <= b[n] ; i++ ){
rebuild( i );
}
int op,l,r,x;
while( q -- ){
scanf("%d",&op);
if( op == 1 ){
scanf("%d%d%d",&l,&r,&x);
update( l , r , x );
}else{
scanf("%d",&x);
int res = query(x);
printf("%d\n",res);
}
}
return 0 ;
}