题目链接 GukiZ and GukiZiana

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

$n <= 500000, q <= 50000$

我一开始的反应是线段树,然后发现自己完全想错了……

这道题时限$10$秒,但也很容易超时。我后来是用分块过的。

把序列分成$\sqrt{n}$个块,每个块的大小为$\sqrt{n}$(最后一个块可能因为不能整除的关系可能会小一些)

每个块维护一个值$delta[i]$,表示这块的每一个数值都要加上这个值。

第1种操作的时候,找到$l$和$r$所在的块。

这两个块之间(不包含$l$所在的块和$r$所在的块,如果没有就不修改)的所有块的$delta$都加上$x$

这样就降低了修改的时间复杂度

$l$所在的块中的元素依次遍历,若下标满足$l <= i <= r$,则值加$x$

$r$所在的块中的元素依次遍历,若下标满足$l <= i <= r$,则值加$x$

每个块内按照值升序排序(第二关键字为下标)

当一个块的整体大小顺序可能发生改变时,就对这个块内部$sort$一遍,当然没必要$sort$的时候不要$sort$

不然可能$TLE$

查询的时候对每个块二分查找,找到值为$x$的元素的下标,并实时更新答案。

时间复杂度$O(q\sqrt{n}log(\sqrt{n}))$

#include <bits/stdc++.h>

using namespace std;

#define rep(i, a, b)	for (int i(a); i <= (b); ++i)
#define dec(i, a, b) for (int i(a); i >= (b); --i)
#define fi first
#define se second typedef long long LL; const int N = 500010;
const int Q = 810; int block_size, block_num, n, q, c[N], cnt, et, op, l, r;
LL a[N], delta[N], x;
vector <pair<LL, int> > block[Q]; void update(int l, int r, LL x){ rep(i, c[l] + 1, c[r] - 1)
delta[i] += x; for (auto &node : block[c[l]])
if (node.se >= l && node.se <= r)
node.fi += x; sort(block[c[l]].begin(), block[c[l]].end()); if (c[r] > c[l]){
for (auto &node : block[c[r]])
if (node.se >= l && node.se <= r)
node.fi += x; sort(block[c[r]].begin(), block[c[r]].end()); } } void query(LL x){
int L = 1 << 30, R = -1;
rep(i, 1, block_num){
auto it = lower_bound(block[i].begin(), block[i].end(), make_pair(x - delta[i], 0));
if (it != block[i].end() && it -> first == x - delta[i])
L = min(L, it -> se); it = lower_bound(block[i].begin(), block[i].end(), make_pair(x - delta[i] + 1, 0));
if (it != block[i].begin()){
--it;
if (it -> fi == x - delta[i])
R = max(R, it -> se);
}
} if (~R) printf("%d\n", R - L);
else puts("-1");
} int main(){ scanf("%d%d", &n, &q);
rep(i, 1, n) scanf("%lld", a + i);
block_size = sqrt(n + 0.5); block_num = n / block_size;
if (n % block_size) ++block_num; cnt = 1;
rep(i, 1, n){
++et;
c[i] = cnt;
block[cnt].push_back({a[i], i});
if (et == block_size){
et = 0;
++cnt;
} } rep(i, 1, block_num) sort(block[i].begin(), block[i].end()); for (; q--; ){
scanf("%d", &op);
if (op == 1){
scanf("%d%d%lld", &l, &r, &x);
update(l, r, x);
} else{
scanf("%lld", &x);
query(x);
}
} return 0;
}

Codeforces 551E GukiZ and GukiZiana(分块思想)的更多相关文章

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

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

  2. CodeForces 551E GukiZ and GukiZiana

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

  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: 20 Sec Memory Limit: 256 MB 题目连接 http://codeforces.com/contest/55 ...

  5. Codeforces 307 div2 E.GukiZ and GukiZiana 分块

    time limit per test 10 seconds memory limit per test 256 megabytes input standard input output stand ...

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

  7. Codeforces 551 E - GukiZ and GukiZiana

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

  8. Codeforces Round #319 (Div. 1)C. Points on Plane 分块思想

                                                                              C. Points on Plane On a pl ...

  9. [codeforces551E]GukiZ and GukiZiana

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

随机推荐

  1. mysql 的 case when 用法

    正确的格式: case when condition then result when condition then result when condition then result else re ...

  2. RSA与AES实现数据加密传输

    RSA.AES简介 RSA:非对称加密,需要提前生成两个密钥(一对的),通过其中一个密钥加密后的数据,只有另一个密钥能解密.通常这两个密钥中有一个会暴漏出来,即对外公开的,这个密钥称为“公钥”,反之另 ...

  3. 下载旧版本的JDK

    下载旧版本的JDK 有的时候我们需要去下载旧版本的JDK,但是进入Oracle官网,显示的总是新版的JDK,这里告诉大家怎么样去下载旧版本的JDK. 首先去JavaSE的 下载界面 拉到最下面,找到这 ...

  4. UVALive - 3942 Remember the Word (Trie + DP)

    题意: 给定一篇长度为L的小写字母文章, 然后给定n个字母, 问有多少种方法用这些字母组成文章. 思路: 用dp[i]来表达[i , L]的方法数, 那么dp[i] 就可以从dp[len(x) + i ...

  5. C#中的扩展方法详解

    “扩展方法使您能够向现有类型“添加”方法,而无需创建新的派生类型.重新编译或以其他方式修改原始类型.”这是msdn上说的,也就是你可以对String,Int,DataRow,DataTable等这些类 ...

  6. 使用 D8 分析 javascript 如何被 V8 引擎优化的

    在上一篇文章中我们讲了如何使用 GN 编译 V8 源码,文章最后编译完成的可执行文件并不是 V8,而是 D8.这篇我们讲一下如何使用 D8 调试 javascript 代码. 如果没有 d8,可以使用 ...

  7. URAL 1099 Work scheduling 一般图的最大匹配 带花树算法(模板)

    R - Work scheduling Time Limit:500MS     Memory Limit:65536KB     64bit IO Format:%I64d & %I64u ...

  8. VirtualBox Host-only Adapter,Failed to create the host-only adapter 转

    不用重装VirtualBox,安装虚拟网卡 今天使用VirtualBox的host-only模式,因为之前把网络连接卸载,这次出现的各种错误. Failed to create the host-on ...

  9. CS231n笔记 Lecture 5 Convolutional Neural Networks

    一些ConvNets的应用 Face recognition 输入人脸,推测是谁 Video classfication Recognition 识别身体的部位, 医学图像, 星空, 标志牌, 鲸.. ...

  10. 用-webkit-box-reflect制作倒影

    1.只在webkit内核的浏览器上有效果 2.语法: -webkit-box-reflect: <direction> <offset> <mask-box-image& ...