题目大意:一个长度为$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. UItraIso 制作ubentu 系统失败

    设备忙,请退出所有正在运行的应用程序,按确定按钮重试. 解决方法: 不要使用UItraIso,不知道为什么一直不行.重启了电脑几次都不行.用Rufus吧 https://rufus.ie/ 注意: r ...

  2. 使用vs code写php及调试

    原文来自:http://www.cnblogs.com/CLR010/p/5276077.html 首页先改下php.ini 一般是在最底部,有就修改没有就加上去下面的配置: xdebug.remot ...

  3. 使用QUIC

    QUIC是Google新开发的一个基于UDP的协议,它提供了像TCP一样的传输可靠性保证,可以实现数据传输的0-RTT延迟,灵活的设计使我们可以对它的拥塞控制及流量控制做更多的定制,它还提供了传输的安 ...

  4. spark history server

    参考:http://blog.csdn.net/lsshlsw/article/details/44786575 为什么需要historyServer? 在运行Spark Application的时候 ...

  5. VIN码识别:毫秒间99%精准识别

    科技改变生活.几年前,人工智能还仅是一个噱头,现在已逐渐融入我们的工作和生活,代替了一些重复性的.繁杂的人工劳动,在提高工作效率的同时,提升了客户体验. 车架号也叫VIN码,由17位数字和字母混合组成 ...

  6. cookie的介绍和自动化中cookie的操作

    1 cookie是什么? cookie: 1. Cookie是一小段的文本信息:格式:python中的字典(键值对组成) 2. Cookie产生:客户端请求服务器,如果服务器需要记录该用户状态,就向客 ...

  7. 如何编写 Python 程序

    如何编写 Python 程序 从今以后,保存和运行 Python 程序的标准步骤如下: 对于 PyCharm 用户 打开 PyCharm. 以给定的文件名创建新文件. 输入案例中给出的代码. 右键并运 ...

  8. leetcode-零钱兑换—int溢出

     零钱兑换 给定不同面额的硬币 coins 和一个总金额 amount.编写一个函数来计算可以凑成总金额所需的最少的硬币个数.如果没有任何一种硬币组合能组成总金额,返回 -1. 示例 1: 输入: c ...

  9. 对int类型最小值INT_MIN取负值结果不变

    在32位系统中,int类型的最大值是0x7fffffff(即除了最高的1Bit其他31位都为1),而最小值是0x80000000(除了最高1bit,其他31位都为0). 显然,对于最小值求负数是不存在 ...

  10. NYOJ 35 表达式求值(逆波兰式求值)

    http://acm.nyist.net/JudgeOnline/problemset.php?typeid=4 NYOJ 35 表达式求值(逆波兰式求值) 逆波兰式式也称后缀表达式. 一般的表达式求 ...