题目大意:一个长度为$n(n\leqslant5\times10^5)$的数组,有两个操作:

  1. $1\;l\;r\;x:$把区间$[l,r]$加上$x$
  2. $2\;x:$询问$x$第一次出现和最后一次出现之间的距离,若没出现输出$-1$

题解:分块,把每个块排个序(可以把数值为第一关键字,位置为第二关键字),整块的加就块上打$tag$,非整块的就暴力重构,查询就在每个块内求这个数出现位置,直接二分查找就行了。设块大小为$S$,修改复杂度$O(\dfrac n S+2S)$,查询复杂度$O(\dfrac n S\log_2 S)$,$S$略大于$\sqrt n$最好。

卡点:

C++ Code:

#include <algorithm>
#include <cstdio>
#include <cctype>
namespace IO {
struct istream {
#define M (1 << 24 | 3)
char buf[M], *ch = buf - 1;
inline istream() {
#ifndef ONLINE_JUDGE
freopen("input.txt", "r", stdin);
#endif
fread(buf, 1, M, stdin);
}
inline istream& operator >> (int &x) {
while (isspace(*++ch));
for (x = *ch & 15; isdigit(*++ch); ) x = x * 10 + (*ch & 15);
return *this;
}
inline istream& operator >> (long long &x) {
while (isspace(*++ch));
for (x = *ch & 15; isdigit(*++ch); ) x = x * 10 + (*ch & 15);
return *this;
}
#undef M
} cin;
struct ostream {
#define M (1 << 24 | 3)
char buf[M], *ch = buf - 1;
int w;
inline ostream& operator << (int x) {
if (!x) {
*++ch = '0';
return *this;
}
if (x < 0) *++ch = '-', x = -x;
for (w = 1; w <= x; w *= 10);
for (w /= 10; w; w /= 10) *++ch = (x / w) ^ 48, x %= w;
return *this;
}
inline ostream& operator << (const char x) {*++ch = x; return *this;}
inline ~ostream() {
#ifndef ONLINE_JUDGE
freopen("output.txt", "w", stdout);
#endif
fwrite(buf, 1, ch - buf + 1, stdout);
}
#undef M
} cout;
} #define maxn 500010
const int BSZ = 1 << 10, BNUM = maxn / BSZ + 10; int bel[maxn];
int L[BNUM], R[BNUM];
long long tg[BNUM];
struct node {
long long s;
int id;
inline node() {}
inline node(long long __s, int __id) : s(__s), id(__id) {}
inline node(int __s, int __id) {s = __s, id = __id;}
inline friend bool operator < (const node &lhs, const node &rhs) {
return lhs.s == rhs.s ? lhs.id < rhs.id : lhs.s < rhs.s;
}
} s[maxn]; int n, m, Bnum; int query(const int x) {
int max = 0, min = 0;
for (int i = 1; i <= Bnum; i++) if (tg[i] <= x) {
const int y = x - tg[i];
int l = std::lower_bound(s + L[i], s + R[i], node(y, 0)) - s;
if (l != R[i] && s[l].s == y) {
int r = std::lower_bound(s + L[i], s + R[i], node(y + 1, 0)) - s - 1;
if (!min) min = s[l].id;
max = s[r].id;
}
}
if (!min) return -1;
return max - min;
}
int main() {
IO::cin >> n >> m;
for (int i = 1; i <= n; i++) {
IO::cin >> s[i].s; s[i].id = i;
bel[i] = (i - 1 >> 10) + 1;
} Bnum = bel[n];
for (int i = 1; i <= Bnum; i++) {
L[i] = i - 1 << 10, R[i] = L[i] + BSZ;
}
L[1] = 1, R[Bnum] = n + 1;
for (int i = 1; i <= Bnum; i++) {
std::sort(s + L[i], s + R[i]);
} while (m --> 0) {
int op, l, r, x;
IO::cin >> op >> l;
if (op == 1) {
IO::cin >> r >> x;
const int lb = bel[l], rb = bel[r];
if (lb == rb) {
for (register node *now = s + L[lb]; now != s + R[lb]; ++now) if (l <= now -> id && now -> id <= r) now -> s += x;
std::sort(s + L[lb], s + R[lb]);
} else {
for (register node *now = s + L[lb]; now != s + R[lb]; ++now) if (l <= now -> id) now -> s += x;
std::sort(s + L[lb], s + R[lb]);
for (int i = lb + 1; i < rb; i++) tg[i] += x;
for (register node *now = s + L[rb]; now != s + R[rb]; ++now) if (now -> id <= r) now -> s += x;
std::sort(s + L[rb], s + R[rb]);
}
} else {
IO::cout << query(l) << '\n';
}
}
return 0;
}

  

[CF551E]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 551 E - GukiZ and GukiZiana

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

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

  6. Codeforces 551E GukiZ and GukiZiana(分块思想)

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

  7. [codeforces551E]GukiZ and GukiZiana

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

  8. CodeForces 551E GukiZ and GukiZiana

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

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

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

随机推荐

  1. 测试FlowTable

    1.确定openvswitch模块加载#lsmod |grep oepnvswitch#/sbin/modprobe openvswitch 2.启动配置:1)默认配置rm -f /usr/local ...

  2. 绝地求生大逃杀BE启动失败,应用程序无法正常启动

    今日更新绝地求生大逃杀后部分客户反馈绝地求生点击启动提示BE安装,应用程序无法启动 问题原因:经过排查发现,客户开启过超级工作站运行过游戏,在系统镜像包中保留了旧版的BE服务,致使新版BE无法安装,冲 ...

  3. Ruby 基础教程1-4

    1.对象 数值对象 字符串对象 数组对象,散列对象 正则表达式对象 时间对象 文件对象 符号对象 2.类 Numeric String Array Hash Regexp File Symbol 3. ...

  4. dubbo入门(一)

    1.简介 Dubbo由阿里巴巴开源,是一个分布式服务框架,致力于提供高性能和透明化的RPC(远程过程调用)远程服务调用方案,以及SOA服务治理方案.如果没有分布式的需求,Dbubbo是不需要的,其本质 ...

  5. 【springboot-01】整合quartz

    1.什么是quartz? quartz是一个开源的定时任务框架,具备将定时任务持久化至数据库以及分布式环境下多节点调度的能力.当当的elastic-job便是以quartz为基础,结合zookeepe ...

  6. hdu1175连连看(dfs+细节)

    连连看 Time Limit: 20000/10000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others)Total Submi ...

  7. 一种新的自动化 UI 测试解决方案 Airtest Project

    今天分享一个自动化UI测试工具airtest——一款网易出品的基于图像识别面向游UI测试的工具,也支持原生Android App基于元素识别的UI自动化测试.主要包含了三部分:Airtest IDE. ...

  8. Python 作用域和命名空间

    在介绍类之前,我首先要告诉你一些Python的作用域规则.类定义对命名空间有一些巧妙的技巧,你需要知道作用域和命名空间如何工作才能完全理解正在发生的事情.顺便说一下,关于这个主题的知识对任何高级Pyt ...

  9. (Python爬虫04)了解通用爬虫和聚焦爬虫,还是理论知识.快速入门可以略过的

    如果现在的你返回N年前去重新学习一门技能,你会咋做? 我会这么干: ...哦,原来这个本事学完可以成为恋爱大神啊, 我要掌握精髓需要这么几个要点一二三四..... 具体的学习步骤是这样的一二三.... ...

  10. Struts2(九.利用layer组件实现图片显示功能)

    1.layer前端组件介绍 layer是一款口碑极佳的web弹层组件,她具备全方位的解决方案,致力于服务各个水平段的开发人员,您的页面会轻松地拥有丰富而友好的操作体验. http://sentsin. ...