题意:就是给一个数列,有两种操作
1 l r x从l~r都+x
2 x查询最右边==x的位置-最左边==x的位置
思路:
分块一下就行了
#include<stdio.h>
#include<string.h>
#include<iostream>
#include<algorithm>
#include<math.h>
#include<queue>
#include<stack>
#include<string>
#include<vector>
#include<map>
#include<set>
using namespace std;
#define mem(a,b) memset(a,b,sizeof(a))
#define lowbit(x) (x&(-x))
typedef long long LL;
#define maxn 550005
const int inf=10000005;
LL A[maxn],pos[maxn],add[maxn];
struct node
{
LL val;
int pos;
node(LL a=0,int b=0)
{
val=a,pos=b;
}
bool friend operator <(node u,node v)
{
return u.val<v.val;
}
};
vector<node>vec[50005];
void Add(int l,int r,LL x)
{
int left=pos[l],right=pos[r];
for(int i=left+1;i<right;++i)
add[i]+=x;
if(left==right)
{
int Size=vec[left].size();
for(int i=0;i<Size;++i)
if(vec[left][i].pos>=l&&vec[left][i].pos<=r)
vec[left][i].val+=x;
sort(vec[left].begin(),vec[left].end());
}
else
{
int Size=vec[left].size();
for(int i=0;i<Size;++i)
if(vec[left][i].pos>=l&&vec[left][i].pos<=r)
vec[left][i].val+=x;
Size=vec[right].size();
for(int i=0;i<Size;++i)
if(vec[right][i].pos>=l&&vec[right][i].pos<=r)
vec[right][i].val+=x;
sort(vec[left].begin(),vec[left].end());
sort(vec[right].begin(),vec[right].end());
}
}
int query(int pos,LL x)
{
x-=add[pos];
int r=vec[pos].size()-1,l=0;
while(l<=r)
{
int mid=(l+r)/2;
if(vec[pos][mid].val==x) return 1;
if(vec[pos][mid].val>x) r=mid-1;
else l=mid+1;
}
return 0;
}
int find_min(int pos,LL x)
{
x-=add[pos];
int Size=vec[pos].size();
int tmp=inf;
for(int i=0;i<Size;++i)
if(vec[pos][i].val==x)
tmp=min(tmp,vec[pos][i].pos);
return tmp;
}
int find_max(int pos,LL x)
{
x-=add[pos];
int Size=vec[pos].size();
int tmp=-inf;
for(int i=0;i<Size;++i)
if(vec[pos][i].val==x)
tmp=max(tmp,vec[pos][i].pos);
return tmp;
}
int main()
{
int n,q;
scanf("%d%d",&n,&q);
for(int i=1;i<=n;++i)
scanf("%lld",&A[i]);
int t=sqrt(n),pos1=t,pos2=1;
for(int i=1;i<=n;++i)
if(i<=pos1)
{
vec[pos2].push_back(node(A[i],i));
pos[i]=pos2;
}
else
{
pos1+=t;pos2++;
vec[pos2].push_back(node(A[i],i));
pos[i]=pos2;
}
for(int i=1;i<=pos2;++i)
sort(vec[i].begin(),vec[i].end());
int tot=0;
while(q--)
{
LL x;
scanf("%lld",&x);
if(x==1)
{
int l,r;
scanf("%d%d%lld",&l,&r,&x);
Add(l,r,x);
}
else
{
tot++;
scanf("%lld",&x);
int l=inf,r=-inf;
for(int i=1;i<=pos2;++i)
if(query(i,x))
{
//printf("%d %d\n",l,r);
l=min(i,l);r=max(i,r);
//printf("***%d %d %d\n",l,r,i);
}
if(l!=inf)
{
l=find_min(l,x);r=find_max(r,x);
printf("%d\n",r-l);
}
else printf("-1\n");
//printf("***%d %d\n",l,r);
}
/*printf("%d\n",pos2);
for(int i=1;i<=pos2;++i)
{
int Size=vec[i].size();
for(int j=0;j<Size;++j)
printf("%lld(%d) ",vec[i][j].val+add[i],vec[i][j].pos);
printf("\n");
}*/
}
return 0;
}