Codeforces 551E GukiZ and GukiZiana(分块思想)
题目链接 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(分块思想)的更多相关文章
- Codeforces 551E - GukiZ and GukiZiana(分块)
Problem E. GukiZ and GukiZiana Solution: 先分成N=sqrt(n)块,然后对这N块进行排序. 利用二分查找确定最前面和最后面的位置. #include < ...
- CodeForces 551E GukiZ and GukiZiana
GukiZ and GukiZiana Time Limit: 10000ms Memory Limit: 262144KB This problem will be judged on CodeFo ...
- 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: 20 Sec Memory Limit: 256 MB 题目连接 http://codeforces.com/contest/55 ...
- Codeforces 307 div2 E.GukiZ and GukiZiana 分块
time limit per test 10 seconds memory limit per test 256 megabytes input standard input output stand ...
- 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 551 E - GukiZ and GukiZiana
E - GukiZ and GukiZiana 思路:分块, 块内二分 代码: #pragma GCC optimize(2) #pragma GCC optimize(3) #pragma GCC ...
- Codeforces Round #319 (Div. 1)C. Points on Plane 分块思想
C. Points on Plane On a pl ...
- [codeforces551E]GukiZ and GukiZiana
[codeforces551E]GukiZ and GukiZiana 试题描述 Professor GukiZ was playing with arrays again and accidenta ...
随机推荐
- angular5 HttpInterceptor使用
HttpInterceptor接口是ng的http请求拦截器,当需要拦截http请求,可以实现该接口. 1.创建HttpInterceptor 的实现类,并使用@Injectable()注解 @Inj ...
- poj-1979 red and black(搜索)
Time limit1000 ms Memory limit30000 kB There is a rectangular room, covered with square tiles. Each ...
- JAVA、JDK等入门概念,下载安装JAVA并配置环境变量
一.概念 Java是一种可以撰写跨平台应用程序的面向对象的程序设计语言,具体介绍可查阅百度JAVA百科,这里不再赘述. Java分为三个体系,分别为: Java SE(J2SE,Java2 Platf ...
- 探究灰度测试(A/B Testing)
一段小插曲 前段时间产品改版,产品经理为了改进用户体验,就决定改版用户的注册流程页面,但又怕身份证注册验证接口不稳定(第三方的身份证校验). 于是产品经理就让我通过随机概率去控制注册流程,让一部分用户 ...
- 转 关于oracle 分区表 表空间以及索引的总结
关于oracle的表空间,分区表,以及索引的总结关键字: oracle, 表空间, 分区表, 索引 上周第一次做数据库测试碰到了很多问题特此总结: 表空间: Oracle的UNDOTBS01.DBF文 ...
- SDOJ 1195 Zhenhuan
描述 今日又在看甄嬛传,皇上觉得后宫们的勾心斗角太险恶了,有点不好,决定给每个妃子发丝带以让后宫之间和睦相处.皇上一共有N个后宫(标号为1~n),站成一个环形(1号与n号相邻),每个后宫想要ai个丝带 ...
- Leetcode 474.一和零
一和零 在计算机界中,我们总是追求用有限的资源获取最大的收益. 现在,假设你分别支配着 m 个 0 和 n 个 1.另外,还有一个仅包含 0 和 1 字符串的数组. 你的任务是使用给定的 m 个 0 ...
- HttpRunner自动化框架学习笔记
一.简单介绍 HttpRunner 是一款面向 HTTP(S) 协议的通用测试框架,只需编写维护一份 YAML/JSON 脚本,即可实现自动化测试.性能测试.线上监控.持续集成等多种测试需求. 支持p ...
- POJ——2236Wireless Network(暴力并查集)
Wireless Network Time Limit: 10000MS Memory Limit: 65536K Total Submissions: 22107 Accepted: 928 ...
- ACM程序设计选修课——Problem D: (ds:树)合并果子(最优二叉树赫夫曼算法)
Problem D: (ds:树)合并果子 Time Limit: 5 Sec Memory Limit: 64 MB Submit: 80 Solved: 4 [Submit][Status][ ...