省队集训 Day6 序列
【题目大意】
给出$n$个数的序列$a_1, a_2, ..., a_n$,有$m$次操作,为下面三种:
$A~l~r~d$:区间$[l,r]$,全部加$d$。
$M~l~r~d$:区间$[l,r]$,对$d$取max。
$Q~x$:询问$a_x$的值。
对于30%的数据,$n, m\leq 10^4$;
对于60%的数据,保证数据随机;
对于100%的数据,满足$n, m \leq 10^5$,所有数的绝对值不超过$2^{31} - 1$。保证也是随机的。
【题解】
显然正解是吉司机线段树,我不会,那怎么办?分块!!!
对于100%的数据的那个性质我是拿数据后才知道的。
考场写了$O(n * (n/B) * logB)$的常数大的跟*一样的分块做法,其中$B = 32$,理论上$B = 128$左右比较优,可能是我常数太大了只能开32。。。
由于数据随机(迷),就过了……
具体是这样的,每个操作如果涉及部分块,直接暴力重构。
每个块内排序后,发现操作2相当于找一段前缀,改成$d$,然后将这些数的次数全部+1,这个可以方便用线段树维护,找的话线段树上二分即可。
操作1的话相当于块全局加,然后这些块的次数全部+1(需要特判$d=0$),可以记录一个全局标记来做。
然后就很方便维护信息了(吧),为了线段树上二分可能需要记录一个最小值。
然后调调边界啊,开开longlong啊,卡了卡常就过了。。
# include <stdio.h>
# include <assert.h>
# include <string.h>
# include <iostream>
# include <algorithm>
# define getchar getchar_unlocked using namespace std; typedef long long ll;
typedef unsigned long long ull;
typedef long double ld; # ifdef WIN32
# define LLFORMAT "%I64d"
# else
# define LLFORMAT "%lld"
# endif # define beg BEG
# define end END const int N = 1e5 + , B = , SN = + ;
const ll inf = 1e17; inline int getint() {
int x = , f = ; char ch = getchar();
while(!isdigit(ch)) {
if(ch == '-') f = ;
ch = getchar();
}
while(isdigit(ch)) x = (x<<) + (x<<) + ch - '', ch = getchar();
return f ? x : -x;
} int n, m, beg[B], end[B], len[B], bl[N], id[B][]; struct pa {
ll a; int t;
pa() {}
pa(ll a, int t) : a(a), t(t) {}
inline friend bool operator < (pa a, pa b) {
return a.a < b.a;
}
inline friend pa operator + (pa a, pa b) {
return pa(min(a.a, b.a), );
}
}p[N]; pa g[B]; int gn = ;
ll add[B]; int addt[B];
struct SMT {
// 区间覆盖,对于a做,区间加法,对于t做
pa w[SN]; int tag[SN]; ll cov[SN]; bool hc[SN];
# define ls (x<<)
# define rs (x<<|)
inline void up(int x) {
w[x] = w[ls] + w[rs];
}
inline void pushtag(int x, int tg) {
tag[x] += tg; w[x].t += tg;
}
inline void pushcov(int x, ll c) {
w[x].a = c; cov[x] = c; hc[x] = ;
}
inline void down(int x) {
if(hc[x]) {
pushcov(ls, cov[x]); pushcov(rs, cov[x]);
hc[x] = ; cov[x] = ;
}
if(tag[x]) {
pushtag(ls, tag[x]); pushtag(rs, tag[x]);
tag[x] = ;
}
}
inline void build(int x, int l, int r) {
tag[x] = cov[x] = ; hc[x] = ;
if(l == r) {
w[x] = g[l];
return ;
}
int mid = l+r>>;
build(ls, l, mid); build(rs, mid+, r);
up(x);
}
inline void cover(int x, int l, int r, int L, int R, ll p) {
if(L <= l && r <= R) {
pushcov(x, p);
pushtag(x, );
return ;
}
down(x);
int mid = l+r>>;
if(L <= mid) cover(ls, l, mid, L, R, p);
if(R > mid) cover(rs, mid+, r, L, R, p);
up(x);
}
inline void gans(int x, int l, int r) {
if(l == r) {
g[++gn] = w[x];
return ;
}
down(x);
int mid = l+r>>;
gans(ls, l, mid); gans(rs, mid+, r);
}
inline pa gs(int x, int l, int r, int ps) {
// cerr << x << ' ' << w[x].a << ' ' << w[x].t << endl;
if(l == r) return w[x];
down(x);
int mid = l+r>>;
if(ps <= mid) return gs(ls, l, mid, ps);
else return gs(rs, mid+, r, ps);
}
// find the last number that < p
inline int find(int x, int l, int r, ll p) {
if(l == r) return l;
down(x);
int mid = l+r>>;
if(w[rs].a < p) return find(rs, mid+, r, p);
else return find(ls, l, mid, p);
} inline void debug(int x, int l, int r) {
printf("x = %d, min = " LLFORMAT "\n", x, w[x].a);
if(l == r) {
printf(" times = %d\n", w[x].t);
return ;
}
int mid = l+r>>;
debug(ls, l, mid);
debug(rs, mid+, r);
}
# undef ls
# undef rs
}T[B]; int tid[B];
inline bool cmp(int x, int y) {
return p[x] < p[y];
} namespace prepare {
inline void deal(int x) {
register int *pid = id[x], Len; Len = len[x] = end[x] - beg[x] + ;
for (register int i=; i<=Len; ++i) tid[i] = beg[x] + i - ;
sort(tid+, tid+Len+, cmp);
for (register int i=; i<=Len; ++i) g[i] = p[tid[i]];
T[x].build(, , Len);
for (register int i=; i<=Len; ++i) pid[i] = tid[i];
}
} namespace option1 {
inline void deal(int x, int l, int r, int c) {
register int *pid = id[x], Len = len[x];
gn = , T[x].gans(, , Len);
for (register int i=; i<=Len; ++i) p[pid[i]] = g[i], tid[i] = beg[x] + i - ;
for (register int i=beg[x]; i<=end[x]; ++i) p[i].a += add[x], p[i].t += addt[x];
add[x] = ; addt[x] = ;
for (register int i=l; i<=r; ++i) p[i].a += c, p[i].t ++;
sort(tid+, tid+Len+, cmp);
for (register int i=; i<=Len; ++i) g[i] = p[tid[i]];
T[x].build(, , Len);
for (register int i=; i<=Len; ++i) pid[i] = tid[i];
}
inline void deal(int x, int c) {
add[x] += c; addt[x] ++;
}
inline void main(int l, int r, int c) {
register int L = bl[l], R = bl[r];
if(L == R) deal(L, l, r, c);
else {
deal(L, l, end[L], c);
deal(R, beg[R], r, c);
for (register int i=L+; i<R; ++i) deal(i, c);
}
}
} namespace option2 {
inline void deal(int x, int l, int r, int c) {
register int *pid = id[x], Len = len[x];
gn = , T[x].gans(, , Len);
for (register int i=; i<=Len; ++i) p[pid[i]] = g[i], tid[i] = beg[x] + i - ;
for (register int i=beg[x]; i<=end[x]; ++i) p[i].a += add[x], p[i].t += addt[x];
add[x] = ; addt[x] = ;
for (register int i=l; i<=r; ++i)
if(p[i].a < c) p[i].a = c, p[i].t ++;
sort(tid+, tid+Len+, cmp);
for (register int i=; i<=Len; ++i) g[i] = p[tid[i]];
// for (int i=1; i<=len[x]; ++i) cerr << g[i].a << ' ' << g[i].t << " ====\n";
T[x].build(, , Len);
for (register int i=; i<=Len; ++i) pid[i] = tid[i];
// for (int i=1; i<=len[x]; ++i) cerr << id[x][i] << ' '; cout << " id end\n";
}
inline void deal(int x, int c) {
ll p = c - add[x];
if(T[x].w[].a >= p) return ;
else {
int tp = T[x].find(, , len[x], p);
T[x].cover(, , len[x], , tp, p);
}
}
inline void main(int l, int r, int c) {
register int L = bl[l], R = bl[r];
if(L == R) deal(L, l, r, c);
else {
deal(L, l, end[L], c);
deal(R, beg[R], r, c);
for (register int i=L+; i<R; ++i) deal(i, c);
}
}
} namespace option3 {
inline pa main(int x) {
register int X = bl[x], *pid = id[X]; pa ret = pa(-inf, );
for (register int i=; i<=len[X]; ++i)
if(pid[i] == x) {
ret = T[X].gs(, , len[X], i);
break;
}
if(ret.a != -inf) ret.a += add[X];
ret.t += addt[X];
return ret;
}
} int main() {
freopen("seq4.in", "r", stdin);
freopen("seq.out", "w", stdout);
const int BB = ;
n = getint();
for (register int i=; i<=n; ++i) p[i] = pa(getint(), );
for (register int i=; i<=n; ++i) bl[i] = (i-)/BB + ;
m = bl[n];
for (register int i=; i<=m; ++i) beg[i] = (i-)*BB+, end[i] = i*BB; end[m] = n;
for (register int i=; i<=m; ++i) prepare :: deal(i);
int Q = getint();
static int l, r, c;
static char ch;
pa t;
while(Q--) {
ch = getchar();
while(!isupper(ch)) ch = getchar();
// T[1].debug(1, 1, len[1]);
// for (int i=1; i<=len[1]; ++i) cout << id[1][i] << ' '; cout << endl;
if(ch == 'A') {
l = getint(), r = getint(), c = getint();
if(!c) continue;
option1 :: main(l, r, c);
} else if(ch == 'M') {
l = getint(), r = getint(), c = getint();
option2 :: main(l, r, c);
} else {
l = getint();
t = option3 :: main(l);
printf(LLFORMAT " %d\n", t.a, t.t);
}
}
return ;
}
省队集训 Day6 序列的更多相关文章
- 省队集训day6 C
Description 给定平面上的 N 个点, 其中有一些是红的, 其他是蓝的.现在让你找两条平行的直线, 使得在保证 不存在一个蓝色的点 被夹在两条平行线之间,不经过任何一个点, 不管是蓝色 ...
- 省队集训day6 B
一道AC自动机题···· 一定要把一个节点没有的儿子接到它fai的儿子,否则会卡到n^2的······· #include<cstdio> #include<iostream> ...
- 省队集训day6 A
code: #include<cstdio> #include<iostream> #include<cmath> #include<cstring> ...
- [2018HN省队集训D8T1] 杀毒软件
[2018HN省队集训D8T1] 杀毒软件 题意 给定一个 \(m\) 个01串的字典以及一个长度为 \(n\) 的 01? 序列. 对这个序列进行 \(q\) 次操作, 修改某个位置的字符情况以及查 ...
- [2018HN省队集训D1T3] Or
[2018HN省队集训D1T3] Or 题意 给定 \(n\) 和 \(k\), 求长度为 \(n\) 的满足下列条件的数列的数量模 \(998244353\) 的值: 所有值在 \([1,2^k)\ ...
- HN2018省队集训
HN2018省队集训 Day1 今天的题目来自于雅礼的高二学长\(dy0607\). 压缩包下载 密码: 27n7 流水账 震惊!穿着该校校服竟然在四大名校畅通无阻?霸主地位已定? \(7:10\)从 ...
- 2018HN省队集训
HNOI2018省队集训 Day 1 流水账 T1 tree 换根+求\(lca\)+求子树和,一脸bzoj3083遥远的国度的既视感.子树和讨论一下就好了,\(lca\)?也是大力讨论一波. 先写了 ...
- 2019暑期金华集训 Day6 杂题选讲
自闭集训 Day6 杂题选讲 CF round 469 E 发现一个数不可能取两次,因为1,1不如1,2. 发现不可能选一个数的正负,因为1,-1不如1,-2. hihoCoder挑战赛29 D 设\ ...
- 2019暑期金华集训 Day6 计算几何
自闭集训 Day6 计算几何 内积 内积不等式: \[ (A,B)^2\le (A,A)(B,B) \] 其中\((A,B)\)表示\(A\cdot B\). (好像是废话?) 叉积 \[ A\tim ...
随机推荐
- P4编程环境搭建遇到的问题与解决方法
在经历了无数的折腾之后,算是折腾,最后采用的是陈翔学长的脚本加上可爱的shell调整装好的. 链接:p4Install 也许是ubuntu18.04的问题,也有可能是我自己把这个系统折腾的有点杂乱的原 ...
- Java常用类之Math类
Java 的常用类Math类: java.lang.Math 提供了系列的静态方法用于科学计算,其方法的参数和返回值类型一般为 double 类型. 如: 1. public static final ...
- TCP系列40—拥塞控制—3、慢启动和拥塞避免概述
本篇中先介绍一下慢启动和拥塞避免的大概过程,下一篇中将会给出多个linux下reno拥塞控制算法的wireshark示例,并详细解释慢启动和拥塞避免的过程. 一.慢启动(slow start) 一个T ...
- Nautilus-Share-Message: Called "net usershare info" but it failed: Failed to
See what nautilus processes are running : ps aux | grep nautilus Kill all nautilus processes you see ...
- JAVA学习之HashCode
public native int hashCode(); 返回该对象的哈希码值.支持此方法是为了提高哈希表(例如 java.util.Hashtable 提供的哈希表)的性能. 一.HashCode ...
- centos7 nginx端口转发出现502的其中一种原因
在排查了一系列可能的原因后仍无法解决,经资料查阅可能是SELinux造成,SELinux很强大但若配置不当也会造成很多组件无法正常使用,这里直接将其关闭: //打开配置文件 vi /etc/selin ...
- Android UI设计的基本元素有哪些
在android app开发如火如荼的今天,如何让自己的App受人欢迎.如何增加app的下载量和使用量....成为很多android应用开发前,必须讨论的问题.而ui设计则是提升客户视觉体验度.提升下 ...
- 【题解】Atcoder AGC#16 E-Poor Turkeys
%拜!颜神怒A此题,像我这样的渣渣只能看看题解度日╭(╯^╰)╮在这里把两种做法都记录一下吧~ 题解做法:可以考虑单独的一只鸡 u 能否存活.首先我们将 u 加入到集合S.然后我们按照时间倒序往回推, ...
- [JSOI2009]计数问题 二维树状数组
---题面--- 题解: 二维树状数组的板子题,,,学了这么久第一次写二维树状数组,惭愧啊. 怎么写就不说了,看代码吧. 跟普通的是一样的写法 #include<bits/stdc++.h> ...
- Android中WebView的跨域漏洞分析和应用被克隆问题情景还原(免Root获取应用沙盒数据)
一.前言 去年年底支付宝的被克隆漏洞被爆出,无独有偶就是腾讯干的,其实真正了解这个事件之后会发现,感觉是针对支付宝.因为这个漏洞找出肯定花费了很大劲,主要是因为支付宝的特殊业务需要开启了WebView ...