[codeforces551E]GukiZ and GukiZiana
试题描述
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:
- First type has form 1 l r x and asks you to increase values of all ai such that l ≤ i ≤ r by the non-negative integer x.
- Second type has form 2 y and asks you to find value of GukiZiana(a, y).
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.
输出
输入示例
4 3 1 2 3 4 1 1 2 1 1 1 1 1 2 3
输出示例
2
数据规模及约定
见“输入”
题解
分块,每块内排序,查找的时候在块内二分。
#include <iostream> #include <cstdio> #include <cstdlib> #include <cstring> #include <cctype> #include <algorithm> #include <cmath> using namespace std; const int BufferSize = 1 << 16; char buffer[BufferSize], *Head, *Tail; inline char Getchar() { if(Head == Tail) { int l = fread(buffer, 1, BufferSize, stdin); Tail = (Head = buffer) + l; } return *Head++; } int read() { int x = 0, f = 1; char c = Getchar(); while(!isdigit(c)){ if(c == '-') f = -1; c = Getchar(); } while(isdigit(c)){ x = x * 10 + c - '0'; c = Getchar(); } return x * f; } #define maxn 500010 #define maxbl 710 #define maxlen 710 #define LL long long int n, blid[maxn], cb, st[maxbl], en[maxbl], len[maxbl]; LL A[maxn], Ord[maxbl][maxlen], addv[maxbl]; void build_sort(int b) { for(int i = st[b]; i <= en[b]; i++) Ord[b][i-st[b]] = A[i]; sort(Ord[b], Ord[b] + len[b]); return ; } void pushdown(int b) { for(int i = st[b]; i <= en[b]; i++) A[i] += addv[b]; addv[b] = 0; return ; } void add(int ql, int qr, int v) { if(blid[ql] == blid[qr]) { int b = blid[ql]; pushdown(b); for(int i = ql; i <= qr; i++) A[i] += v; build_sort(b); return ; } int bl = blid[ql], br = blid[qr]; pushdown(bl); pushdown(br); for(int i = ql; i <= en[bl]; i++) A[i] += v; for(int i = st[br]; i <= qr; i++) A[i] += v; build_sort(bl); build_sort(br); for(int i = bl + 1; i <= br - 1; i++) addv[i] += v; return ; } bool Find(int b, LL y) { int p = lower_bound(Ord[b], Ord[b] + len[b], y - addv[b]) - Ord[b]; return y - addv[b] == Ord[b][p]; } int main() { n = read(); int q = read(); int m = sqrt(n + .5); for(int i = 1; i <= n; i++) { A[i] = read(); int bl = (i - 1) / m + 1; cb = max(cb, bl); blid[i] = bl; if(!st[bl]) st[bl] = i; en[bl] = i; } for(int i = 1; i <= cb; i++) len[i] = en[i] - st[i] + 1, build_sort(i); while(q--) { int tp = read(); if(tp == 1) { int ql = read(), qr = read(), v = read(); add(ql, qr, v); } else { int y = read(), al = -1, ar = -1; for(int i = 1; i <= cb; i++) if(Find(i, y)) { pushdown(i); build_sort(i); for(int j = st[i]; j <= en[i]; j++) if(y == A[j]) { al = j; break; } break; } if(al == -1){ puts("-1"); continue; } for(int i = cb; i; i--) if(Find(i, y)) { pushdown(i); build_sort(i); for(int j = en[i]; j >= st[i]; j--) if(y == A[j]) { ar = j; break; } break; } printf("%d ", ar - al); } } return 0; }