time limit per test

10 seconds

memory limit per test

256 megabytes

input

standard input

output

standard output

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 yGukiZiana(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:

  1. 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.
  2. 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!

Input

The first line contains two integers nq (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.

Output

For each query of type 2, print the value of GukiZiana(a, y), for y value for that query.

Examples
input
4 3
1 2 3 4
1 1 2 1
1 1 1 1
2 3
output
2
input
2 3
1 2
1 2 2 1
2 3
2 4
output
0
-1 题意:给你一个n个数的序列,以及q个操作,有两种操作,1是区间[l,r]上的每个数加上v 2是查询y,求aj = ai = y的最大j-i
思路:我想到分块的做法,分为tb块,每一块中的每个元素保存v和id,然后每一块按v排序,相等按id排序,这样对于查询的时候,我们只需要从左到右找到第一块满足存在y,那么pl = lowwer_bound(y)。同理从右到左找到第一块满足存在y,那么pr = upper_bound(y)。 答案就是pr-pl。
对于更新操作,区间[l,r]所覆盖的块中,第一块和最后一块暴力更新,并且重建块,即重新排序。而对于中间的完整覆盖的块,我们只记录增量add[b],因为add[b]表示b整块的增量,那么b快依然有序,在b块查询x的时候,x -= add[b]即可。 做法很快想好了,但wa了好多发,就是以为不会爆ll。。。
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
const int N = 5e5 + ;
const int SIZE = ;
struct Block {
ll v; int id;
Block() {}
Block(ll v, int id) : v(v), id(id) {}
friend bool operator < (Block a, Block b) {
if(a.v == b.v) return a.id < b.id;
return a.v < b.v;
};
};
Block block[N/SIZE + ][SIZE + ];
int n, q;
ll A[N];
ll add[N/SIZE + ];
int tb, ls; void init() {
scanf("%d%d", &n, &q);
int b = , j = ;
for(int i = ; i < n; ++i) {
scanf("%I64d", &A[i]);
block[b][j] = Block(A[i], i);
if(++j == SIZE) { b++; j = ;}
}
ls = ;
for(int i = ; i < b; ++i) sort(block[i], block[i] + SIZE);
if(j) { ls = j; sort(block[b], block[b] + j); }
tb = b;
}
void rebuild(int b, int sz) {
int j = ;
for(int i = b * SIZE; i < b * SIZE + sz; ++i) block[b][j++] = Block(A[i], i);
sort(block[b], block[b] + j);
}
void update(int L, int R, int v) {
int lb = L / SIZE, rb = R / SIZE, j, sz;
if(lb == rb) {
for(int i = L; i <= R; ++i) A[i] += v;
if(lb == tb) sz = ls;
else sz = SIZE;
rebuild(lb, sz);
}else {
for(int i = L; i < (lb + ) * SIZE; ++i) A[i] += v;
rebuild(lb, SIZE); for(int i = rb * SIZE; i <= R; ++i) A[i] += v;
if(rb == tb) sz = ls;
else sz = SIZE;
rebuild(rb, sz);
for(int b = lb + ; b < rb; ++b) add[b] += v;
}
}
int upper(Block a[], int sz, ll v) {
int L = , R = sz;
while(R - L > ) {
int M = (L + R) >> ;
if(a[M].v <= v) L = M;
else R = M;
}
return L;
}
int lower(Block a[], int sz, ll v) {
int L = , R = sz;
while(L < R) {
int M = (L + R) >> ;
if(a[M].v >= v) R = M;
else L = M + ;
}
return L;
}
int query(ll x) {
int pl = -, pr = -;
ll v;
if(tb == ) {
for(int i = ; i < ls; ++i) if(A[i] == x) { pl = i; break; }
for(int i = ls - ; i >= ; --i) if(A[i] == x) { pr = i; break; }
if(pl == -) return -;
}else {
if(ls) for(int i = tb * SIZE + ls - ; i >= tb * SIZE; --i) if(A[i] == x) { pr = i; break; }
if(pr == -) {
for(int b = tb - ; b >= ; --b) {
v = x - add[b];
int px = upper(block[b], SIZE, v);
if(px < SIZE && block[b][px].v == v) { pr = block[b][px].id; break; }
}
}
if(pr == -) return -;
for(int b = ; b < tb; ++b) {
v = x - add[b];
int pi = lower(block[b], SIZE, v);
if(pi < SIZE && block[b][pi].v == v) { pl = block[b][pi].id; break; }
}
if(pl == -) {
for(int i = tb * SIZE; i < tb * SIZE + ls; ++i) if(A[i] == x) { pl = i; break; }
}
}
return pr - pl;
}
int main() {
//freopen("in.txt", "r", stdin);
init();
int op, l, r, x;
memset(add, , sizeof add);
for(int i = ; i < q; ++i) {
scanf("%d", &op);
if(op == ) {
scanf("%d%d%d", &l, &r, &x);
l--; r--;
update(l, r, x);
}else {
scanf("%d", &x);
printf("%d\n", query(x));
}
}
return ;
}

Codeforces 307 div2 E.GukiZ and GukiZiana 分块的更多相关文章

  1. Codeforces Round #307 (Div. 2) E. GukiZ and GukiZiana 分块

    E. GukiZ and GukiZiana Time Limit: 20 Sec Memory Limit: 256 MB 题目连接 http://codeforces.com/contest/55 ...

  2. Codeforces 551E - GukiZ and GukiZiana(分块)

    Problem E. GukiZ and GukiZiana Solution: 先分成N=sqrt(n)块,然后对这N块进行排序. 利用二分查找确定最前面和最后面的位置. #include < ...

  3. CF 551E. GukiZ and GukiZiana [分块 二分]

    GukiZ and GukiZiana 题意: 区间加 给出$y$查询$a_i=a_j=y$的$j-i$最大值 一开始以为和论文CC题一样...然后发现他带修改并且是给定了值 这样就更简单了.... ...

  4. Codeforces Round #307 (Div. 2) E. GukiZ and GukiZiana(分块)

    E. GukiZ and GukiZiana time limit per test 10 seconds memory limit per test 256 megabytes input stan ...

  5. Codeforces 551E GukiZ and GukiZiana(分块思想)

    题目链接 GukiZ and GukiZiana 题目大意:一个数列,支持两个操作.一种是对区间$[l, r]$中的数全部加上$k$,另一种是查询数列中值为$x$的下标的最大值减最小值. $n < ...

  6. CodeForces 551E GukiZ and GukiZiana

    GukiZ and GukiZiana Time Limit: 10000ms Memory Limit: 262144KB This problem will be judged on CodeFo ...

  7. Codeforces 551 E - GukiZ and GukiZiana

    E - GukiZ and GukiZiana 思路:分块, 块内二分 代码: #pragma GCC optimize(2) #pragma GCC optimize(3) #pragma GCC ...

  8. [codeforces551E]GukiZ and GukiZiana

    [codeforces551E]GukiZ and GukiZiana 试题描述 Professor GukiZ was playing with arrays again and accidenta ...

  9. Codeforces #180 div2 C Parity Game

    // Codeforces #180 div2 C Parity Game // // 这个问题的意思被摄物体没有解释 // // 这个主题是如此的狠一点(对我来说,),不多说了这 // // 解决问 ...

随机推荐

  1. Top 5 iPad Pro Apps for Your Apple Pencil

    1. Procreate - 5 to 10 dollars 2. Adobe Sketch - Free 3. Paper - Free 4. Pixelmator 5. Notes

  2. 深入理解javascript原型和闭包(7)——原型的灵活性

    在Java和C#中,你可以简单的理解class是一个模子,对象就是被这个模子压出来的一批一批月饼(中秋节刚过完).压个啥样,就得是个啥样,不能随便动,动一动就坏了. 而在javascript中,就没有 ...

  3. 【bzoj1076】[SCOI2008]奖励关

    题目描述 你正在玩你最喜欢的电子游戏,并且刚刚进入一个奖励关.在这个奖励关里,系统将依次随机抛出k次宝物,每次你都可以选择吃或者不吃(必须在抛出下一个宝物之前做出选择,且现在决定不吃的宝物以后也不能再 ...

  4. C#高级编程笔记 Day 7, 2016年9月 19日 (泛型)

    1.协变和抗变 泛型接口的协变 如果泛型类型用 out  关键字标注,泛型接口就是协变的.这也意味着返回类型只能是 T. 接口IIndex 与类型T 是协变的,并从一个制度索引器中返回这个类型. pu ...

  5. java26

    1:网络编程(理解)    (1)网络编程:用Java语言实现计算机间数据的信息传递和资源共享    (2)网络编程模型    (3)网络编程的三要素        A:IP地址           ...

  6. javascript闭包和作用域链

    最近在学习前端知识,看到javascript闭包这里总是云里雾里.于是翻阅了好多资料记录下来本人对闭包的理解. 首先,什么是闭包?看了各位大牛的定义和描述各式各样,我个人认为最容易一种说法: 外部函数 ...

  7. objccn-图片格式

    图像格式存储:位图和矢量图像.位图把值存在阵列中,矢量格式存储的是绘图图像的指令.还有混合格式PostScript能够排布字母甚至位图,使其成为了一个非常灵活的方式.衍生格式pdf. xcdoe6已经 ...

  8. Git教程推荐

    推荐:廖雪峰的官方网站-Git教程,面向初学者,浅显易懂.

  9. java 深入技术三(List)

    List ArrayList List接口 List接口的父接口-Collection List接口的重要子类- ArrayList -LikedList List接口不重要子类-Vector jav ...

  10. layer使用方法

    type - 基本层类型 类型:Number,默认:0 layer提供了5种层类型.可传入的值有:0(信息框,默认)1(页面层)2(iframe层)3(加载层)4(tips层). 若你采用layer. ...