[CF551E]GukiZ and GukiZiana
题目大意:一个长度为$n(n\leqslant5\times10^5)$的数组,有两个操作:
- $1\;l\;r\;x:$把区间$[l,r]$加上$x$
- $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的更多相关文章
- 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 551 E - GukiZ and GukiZiana
E - GukiZ and GukiZiana 思路:分块, 块内二分 代码: #pragma GCC optimize(2) #pragma GCC optimize(3) #pragma GCC ...
- 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 < ...
- [codeforces551E]GukiZ and GukiZiana
[codeforces551E]GukiZ and GukiZiana 试题描述 Professor GukiZ was playing with arrays again and accidenta ...
- CodeForces 551E GukiZ and GukiZiana
GukiZ and GukiZiana Time Limit: 10000ms Memory Limit: 262144KB This problem will be judged on CodeFo ...
- Codeforces 307 div2 E.GukiZ and GukiZiana 分块
time limit per test 10 seconds memory limit per test 256 megabytes input standard input output stand ...
随机推荐
- UItraIso 制作ubentu 系统失败
设备忙,请退出所有正在运行的应用程序,按确定按钮重试. 解决方法: 不要使用UItraIso,不知道为什么一直不行.重启了电脑几次都不行.用Rufus吧 https://rufus.ie/ 注意: r ...
- 使用vs code写php及调试
原文来自:http://www.cnblogs.com/CLR010/p/5276077.html 首页先改下php.ini 一般是在最底部,有就修改没有就加上去下面的配置: xdebug.remot ...
- 使用QUIC
QUIC是Google新开发的一个基于UDP的协议,它提供了像TCP一样的传输可靠性保证,可以实现数据传输的0-RTT延迟,灵活的设计使我们可以对它的拥塞控制及流量控制做更多的定制,它还提供了传输的安 ...
- spark history server
参考:http://blog.csdn.net/lsshlsw/article/details/44786575 为什么需要historyServer? 在运行Spark Application的时候 ...
- VIN码识别:毫秒间99%精准识别
科技改变生活.几年前,人工智能还仅是一个噱头,现在已逐渐融入我们的工作和生活,代替了一些重复性的.繁杂的人工劳动,在提高工作效率的同时,提升了客户体验. 车架号也叫VIN码,由17位数字和字母混合组成 ...
- cookie的介绍和自动化中cookie的操作
1 cookie是什么? cookie: 1. Cookie是一小段的文本信息:格式:python中的字典(键值对组成) 2. Cookie产生:客户端请求服务器,如果服务器需要记录该用户状态,就向客 ...
- 如何编写 Python 程序
如何编写 Python 程序 从今以后,保存和运行 Python 程序的标准步骤如下: 对于 PyCharm 用户 打开 PyCharm. 以给定的文件名创建新文件. 输入案例中给出的代码. 右键并运 ...
- leetcode-零钱兑换—int溢出
零钱兑换 给定不同面额的硬币 coins 和一个总金额 amount.编写一个函数来计算可以凑成总金额所需的最少的硬币个数.如果没有任何一种硬币组合能组成总金额,返回 -1. 示例 1: 输入: c ...
- 对int类型最小值INT_MIN取负值结果不变
在32位系统中,int类型的最大值是0x7fffffff(即除了最高的1Bit其他31位都为1),而最小值是0x80000000(除了最高1bit,其他31位都为0). 显然,对于最小值求负数是不存在 ...
- NYOJ 35 表达式求值(逆波兰式求值)
http://acm.nyist.net/JudgeOnline/problemset.php?typeid=4 NYOJ 35 表达式求值(逆波兰式求值) 逆波兰式式也称后缀表达式. 一般的表达式求 ...