Codeforces 307 div2 E.GukiZ and GukiZiana 分块
10 seconds
256 megabytes
standard input
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!
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.
For each query of type 2, print the value of GukiZiana(a, y), for y value for that query.
4 3
1 2 3 4
1 1 2 1
1 1 1 1
2 3
2
2 3
1 2
1 2 2 1
2 3
2 4
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 分块的更多相关文章
- 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 ...
- Codeforces 551E - GukiZ and GukiZiana(分块)
Problem E. GukiZ and GukiZiana Solution: 先分成N=sqrt(n)块,然后对这N块进行排序. 利用二分查找确定最前面和最后面的位置. #include < ...
- CF 551E. GukiZ and GukiZiana [分块 二分]
GukiZ and GukiZiana 题意: 区间加 给出$y$查询$a_i=a_j=y$的$j-i$最大值 一开始以为和论文CC题一样...然后发现他带修改并且是给定了值 这样就更简单了.... ...
- 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 ...
- Codeforces 551E GukiZ and GukiZiana(分块思想)
题目链接 GukiZ and GukiZiana 题目大意:一个数列,支持两个操作.一种是对区间$[l, r]$中的数全部加上$k$,另一种是查询数列中值为$x$的下标的最大值减最小值. $n < ...
- CodeForces 551E GukiZ and GukiZiana
GukiZ and GukiZiana Time Limit: 10000ms Memory Limit: 262144KB This problem will be judged on CodeFo ...
- Codeforces 551 E - GukiZ and GukiZiana
E - GukiZ and GukiZiana 思路:分块, 块内二分 代码: #pragma GCC optimize(2) #pragma GCC optimize(3) #pragma GCC ...
- [codeforces551E]GukiZ and GukiZiana
[codeforces551E]GukiZ and GukiZiana 试题描述 Professor GukiZ was playing with arrays again and accidenta ...
- Codeforces #180 div2 C Parity Game
// Codeforces #180 div2 C Parity Game // // 这个问题的意思被摄物体没有解释 // // 这个主题是如此的狠一点(对我来说,),不多说了这 // // 解决问 ...
随机推荐
- 为什么全世界都对HTTPS抛出了橄榄枝,HTTPS到底有什么好?HTTPS如何配置?
整个互联网世界,正从"裸奔"向HTTPS时代转型. 淘宝.天猫在2015年完成规模巨大的数据"迁徙",将百万计的页面从HTTP切换到HTTPS:苹果要求所有iO ...
- WMPlayer
WMPlayer视频播放器,AVPlayer的封装,继承UIView,想怎么玩就怎么玩.支持播放mp4.m3u8.3gp.mov,网络和本地视频同时支持.全屏和小屏播放同时支持.自动感应旋转屏幕. 1 ...
- opencv学习
判断是否正确读入的方法: if( argc != 2 || !(src=imread(argv[1], 1)).data ) return -1; --- if( src.empty() ) { re ...
- web开发——写一个简单的表格导出操作
一.前台页面: 主要是一个按钮和一个表格,表格有显示数据,按钮负责将表格中的数据选择性地导出.除此外,可以附加一个小窗口和进度条,用于显示下载进度. 1. 按钮:<a href="ja ...
- (转载)JavaWeb学习总结(五十一)——邮件的发送与接收原理
博客源地址:http://www.cnblogs.com/xdp-gacl/p/4209586.html 一. 邮件开发涉及到的一些基本概念 1.1.邮件服务器和电子邮箱 要在Internet上提供电 ...
- XML Schema and XMLspy notes
Introduction An xml documents consists of elements, attributes and text. There are two structures in ...
- thinkphp3.2.3关于模板使用之一二
1.包含文件 使用场景:比如我们在编写网页布局的时候,可能每一个网页的头和脚是相同的,此时如果给每一个网页分别设置,未免太麻烦了.此时就可以使用带包含文件. 首先检查配置文件查看我们的主题目录在哪儿, ...
- PHP变量作用域(花括号、global、闭包)
花括号 很多语言都以花括号作为作用域界限,PHP中只有函数的花括号才构成新的作用域. <?php if (True) { $a = 'var a'; } var_dump($a); for ($ ...
- Python里*arg 和**kwargs的作用
Hi,伙计们.我发现Python新手们在理解*args和**kwargs这两个魔法变量时都有些困难.他们到底是什么?首先,我先告诉大家一个事实,完整地写*args和**kwargs是不必要的,我们可以 ...
- Dynamic range compression
这段时间终于把手头的东西都搞完了,还剩下一个AEC这个模块,这个模块跟整个系统机制有很大关系,单独的模块意义不大. 另外,刚写完一个分类器,希望能大幅提升音乐流派分类的准确率. 下周正式开搞AEC,把 ...