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

  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 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.

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. java 部分注解说明(待补充)

    内容 所代表的意思 @RequestMapping(params = "save") @ResponseBody 将内容或对象作为http响应正文返回,并调用适合HttpMessa ...

  2. 用U盘安装系统的好用的PE系统:通用PE V6.1下载

    用U盘安装系统的好用的PE系统:通用PE V6.1下载 PE是一款用其他介质(我们最常用的是U盘)启动安装电脑系统的简易操作系统,在XP系统中 最经典的是扬州老毛桃出品的只有100多兆的XP内核的PE ...

  3. 面试题目——《CC150》位操作

    面试题5.1:给定两个32位的整数N与M,以及表示比特位置的i与j.编写一个方法,将M插入N,使得M从N的第j位开始,到第i位结束.假定从j位到i位足以容纳M,也即若M=10011,那么j与i之间至少 ...

  4. 制作wordpress留言板

    总结步骤如下: 1.找到模板目录中的single.php文件,复制single.php并重命名为guestbook.php 2.在guestbook最顶部添加如下代码(用于模板调用) <?php ...

  5. DP专辑

    今天练了一波DP.时间紧迫我就只贴代码了. 20141120 fzu2129 http://acm.fzu.edu.cn/problem.php?pid=2129 不同的子序列个数 //#pragma ...

  6. codeblock 编译googletest

    1.cmake安装 2.codeblock  16.01 3.Google Test 1.7.0 4.PATH路径添加(重启电脑,保证设置的PATH路径生效) 5.python安装 6.编译安装:   ...

  7. (转载)phpcms v9两步实现专题栏目生成路径去掉html和special

    相信很多人都知道,phpcms v9专题是不支持自定义URL的,生成的专题路径是以/HTML/special/开头的.那么如何实现专题栏目生成路径去掉html和special呢?通过修改程序的PHP源 ...

  8. Hadoop 部署过程中的一些问题与解决方案

    环境--> centos7.1 --> jdk1.8 1.JDK卸载与安装 http://blog.csdn.net/czmchen/article/details/41047187 2. ...

  9. runtime的黑魔法

    要说明runtime,首先要明白objc这门语言,是基于C的封装.真是因为runtime,objc才有了面对对象的特性. 也就说,所有objc的语言,在运行时都会转换成C. 也是基于这样的特性,run ...

  10. Java Swing

    参考帖子http://chenchaobox.blog.163.com/blog/static/6043759020127845945569/ http://wenku.baidu.com/link? ...