思路:分块, 块内二分
代码:
#pragma GCC optimize(2) #pragma GCC optimize(3) #pragma GCC optimize(4) #include<bits/stdc++.h> using namespace std; #define fi first #define se second #define pi acos(-1.0) #define LL long long //#define mp make_pair #define pb push_back #define ls rt<<1, l, m #define rs rt<<1|1, m+1, r #define ULL unsigned LL #define pll pair<LL, LL> #define pli pair<LL, int> #define pii pair<int, int> #define piii pair<pii, int> #define mem(a, b) memset(a, b, sizeof(a)) #define fio ios::sync_with_stdio(false);cin.tie(0);cout.tie(0); #define fopen freopen("in.txt", "r", stdin);freopen("out.txt", "w", stout); //head const int N = 5e5 + 10, M = 750; const int INF = 0x3f3f3f3f; int bl[N], blo, n; LL tmp[M], a[N]; vector<pii> block[M]; void reset(int x) { block[x].clear(); for (int i = (x-1)*blo + 1; i <= min(x*blo, n); i++) block[x].pb({a[i], i}); sort(block[x].begin(), block[x].end()); } void update(int l, int r, int x) { if(bl[l] == bl[r]) { for (int i = l; i <= r; i++) a[i] += x; reset(bl[l]); return ; } for (int i = l; i <= bl[l]*blo; i++) a[i] += x; reset(bl[l]); for (int i = bl[l]+1; i <= bl[r]-1; i++) tmp[i] += x; for (int i = (bl[r]-1)*blo+1; i <= r; i++) a[i] += x; reset(bl[r]); } int query(int x) { int l = -1, r = -1; for (int i = 1; i <= bl[n]; i++) { LL t = x - tmp[i]; auto it = lower_bound(block[i].begin(), block[i].end(), pii{t, 0}); if(it != block[i].end() && (*it).fi == t) { if(l == -1) l = r = (*it).se; else r = (*it).se; } it = upper_bound(block[i].begin(), block[i].end(), pii{t, INF}); it--; if((*it).fi == t) { if(l == -1) l = r = (*it).se; else r = (*it).se; } } if(l == -1) return -1; else return r - l; } int main() { int q, ty, l, r, x; scanf("%d %d", &n, &q); blo = sqrt(n); for (int i = 1; i <= n; i++) scanf("%lld", &a[i]); for (int i = 1; i <= n; i++) bl[i] = (i-1)/blo + 1; for (int i = 1; i <= n; i++) block[bl[i]].pb({a[i], i}); for (int i = 1; i <= bl[n]; i++) sort(block[i].begin(), block[i].end()); while(q--) { scanf("%d", &ty); if(ty == 1) { scanf("%d %d %d", &l, &r, &x); update(l, r, x); } else { scanf("%d", &x); printf("%d ", query(x)); } } return 0; }