题意:给一个数组
2种操作:
1. L,R区间内增加 VAL
2.查询 值为VAL的最大区间,即 right( VAL ) - left( VAL )
区间内没VAL 输出 -1
#include <cstdio>
#include <cstring>
#include <cstdlib>
#include <string>
#include <iostream>
#include <algorithm>
#include <sstream>
#include <cmath>
using namespace std;
#include <queue>
#include <stack>
#include <vector>
#include <deque>
#include <set>
#include <map>
#define clc(arr, val) memset(arr, val, sizeof(arr))
#define FOR(i,a,b) for(int i=a;i<=b;i++)
#define IN freopen ("in.txt" , "r" , stdin);
#define OUT freopen ("out.txt" , "w" , stdout);
typedef long long LL;
typedef unsigned long long ULL;
const int MAXN = 600127;
const int MAXM = 6000010;
const int N = 30127;
const int M = 200000;
const int INF = 0x3f3f3f3f;
const LL mod = (LL)1<<32;
const double eps= 1e-8;
const double pi=acos(-1.0);
#define lson l,m, rt<<1
#define rson m+1,r,rt<<1|1
struct node
{
LL num;
int p;
bool operator<(const node &a)const
{
return num != a.num ? num < a.num : p < a.p;
}
}a[MAXN],tmp;
int n,q;
LL up[MAXN];
int add(int l,int r,int all,int B,LL val)
{
if(r-l+1==all) up[B]+=val;
else
{
int rr=min(n,(B+1)*all);
for(int i=B*all;i<rr;i++)
{
if(l<=a[i].p&&a[i].p<=r)
a[i].num+=val;
}
sort(a+B*all,a+rr);
}
}
int find(int &ml,int &mr,int l,int r,LL y)
{
if(y<a[l].num||y>a[r].num) return 0;
tmp.num=y;
tmp.p=-INF;
int ll=lower_bound(a+l,a+r+1,tmp)-a;
if(ll==r+1||a[ll].num!=y) return 0;
tmp.p=INF;
int rr=lower_bound(a+l, a+r+1,tmp)-a-1;
ml=min(ml,a[ll].p);
mr=max(mr,a[rr].p);
}
int main()
{
cin>>n>>q;
clc(up,0);
for(int i=0;i<n;i++)
scanf("%I64d",&a[i].num),a[i].p=i;
int all=sqrt(n),num=0;//每all 个为一块
for(int i=0;i<n;i+=all,num++)//一块内排序
sort(a+i,a+min(i+all,n));
for(int i=0;i<q;i++)
{
int op;
scanf("%d",&op);
LL x;
if(op==1)
{
int l,r;
scanf("%d%d%I64d",&l,&r,&x);
l--,r--;
int inl=l/all,inr=r/all;
for(int j=inl;j<=inr;j++)//对于一个区间
add(max(l,j*all),min(r,(j+1)*all-1),all,j,x);
}
else
{
scanf("%I64d",&x);
int l=INF,r=-INF;
for(int j=0;j<num;j++)//查询每个区间
{
find(l,r,j*all,min((j+1)*all-1,n-1),x-up[j]);
}
if(r-l<0) printf("-1\n");
else printf("%d\n",r-l);
}
}
return 0;
}