Codeforces 307 div2 E.GukiZ and GukiZiana 分块
2016-05-14 11:03
357 查看
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:
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!
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
output
input
output
View Code
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:
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!
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 + 10; const int SIZE = 571; 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 + 1][SIZE + 1]; int n, q; ll A ; ll add[N/SIZE + 1]; int tb, ls; void init() { scanf("%d%d", &n, &q); int b = 0, j = 0; for(int i = 0; i < n; ++i) { scanf("%I64d", &A[i]); block[b][j] = Block(A[i], i); if(++j == SIZE) { b++; j = 0;} } ls = 0; for(int i = 0; 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 = 0; 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 + 1) * 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 + 1; b < rb; ++b) add[b] += v; } } int upper(Block a[], int sz, ll v) { int L = 0, R = sz; while(R - L > 1) { int M = (L + R) >> 1; if(a[M].v <= v) L = M; else R = M; } return L; } int lower(Block a[], int sz, ll v) { int L = 0, R = sz; while(L < R) { int M = (L + R) >> 1; if(a[M].v >= v) R = M; else L = M + 1; } return L; } int query(ll x) { int pl = -1, pr = -1; ll v; if(tb == 0) { for(int i = 0; i < ls; ++i) if(A[i] == x) { pl = i; break; } for(int i = ls - 1; i >= 0; --i) if(A[i] == x) { pr = i; break; } if(pl == -1) return -1; }else { if(ls) for(int i = tb * SIZE + ls - 1; i >= tb * SIZE; --i) if(A[i] == x) { pr = i; break; } if(pr == -1) { for(int b = tb - 1; b >= 0; --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 == -1) return -1; for(int b = 0; 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 == -1) { 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, 0, sizeof add); for(int i = 0; i < q; ++i) { scanf("%d", &op); if(op == 1) { scanf("%d%d%d", &l, &r, &x); l--; r--; update(l, r, x); }else { scanf("%d", &x); printf("%d\n", query(x)); } } return 0; }
View Code
相关文章推荐
- 营销型网站的8大策略
- 实现复数类中的运算符重载
- win下一些小工具
- unix编程(九)进程间通信
- APP开发实战14-APP开发人员所需知识
- jvm中分代垃圾回收和触发垃圾回收
- 如果四位数各位上的数字均是0或2或4或6或8,则统计出满足此条件的个数cnt,并把这些四位数按从大到小的顺序存入数组b中。(160514)
- 3518e 开启第三个串口uart2
- Linux之特殊权限(SUID/SGID/SBIT)
- 在 idea 中使用 gradle 导入maven仓库
- Android 编译ffmpeg
- java String.split()函数的用法分析
- iOS——UITableView的优化
- 手机开发实战14——GSM业务种类2
- 总结
- 常用的正则表达式
- python pip
- QT——启动界面
- linux内核启动head.s
- 安卓中将int值转换为String 将String装换长int