[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\n", ar - al);
}
}
return 0;
}