【学习笔记】数据结构全家桶
前言
2025.10.28:
一时兴起建了这个,原因是刚刚学了KTT qwq
有空就塞这玩意,虽然不知道要塞到什么时候,尽量全地弄。
没事慢慢弄
正文
线段树
KTT
KTT
//https://www.luogu.com.cn/problem/P5693
#include<bits/stdc++.h>
#define rep(i, l, r) for(int i(l);i<=(r);++i)
#define per(i, r, l) for(int i(r);i>=(l);--i)
using namespace std;
namespace IO{
template <typename T>
inline void read(T &x){
x = 0;
static char c;
static bool f;
c = getchar(), f = 0;
while(c<'0'||c>'9'){ if(c == '-')f = 1; c = getchar(); }
while('0'<=c&&c<='9')x = (x << 3) + (x << 1) + (c ^ 48), c = getchar();
x = f ? -x : x;
}
template <typename T,typename ...Types>
inline void read(T &x, Types &...y){
read(x), read(y...);
}
}using namespace IO;
using ll = long long;
const int N = 4e5 + 10;
const ll inf = 1e15;
template <typename T>
inline void ckmin(T &x, T y){ (x > y) && (x = y); }
int n,a[N],qcnt;
namespace KTT{
struct Func{
int k; ll b;
inline friend Func operator +(const Func &a,const Func &b){ return (Func){a.k+b.k,a.b+b.b}; }
inline void add(ll v){ b += k * v; }
};
inline pair<Func, ll> max(Func a, Func b){
if(a.k < b.k || (a.k == b.k && a.b < b.b))swap(a, b);
if(a.b >= b.b)return {a, inf};
return {b, (b.b-a.b)/(a.k-b.k)};
}
struct node{
Func lm, rm, tot, sum;
ll iter;//yu zhi
inline friend node operator +(const node &a,const node &b){
node res; pair<Func, ll> tmp;
res.iter = min(a.iter, b.iter);
tmp = max(a.lm, b.lm + a.sum);
res.lm = tmp.first, ckmin(res.iter, tmp.second);
tmp = max(b.rm, a.rm + b.sum);
res.rm = tmp.first, ckmin(res.iter, tmp.second);
tmp = max(a.tot, b.tot);
ckmin(res.iter, tmp.second);
tmp = max(tmp.first, a.rm + b.lm);
ckmin(res.iter, tmp.second);
res.tot = tmp.first;
res.sum = a.sum + b.sum;
return res;
}
}tr[N << 2];
ll tag[N << 2];
#define ls (p << 1)
#define rs (p << 1 | 1)
inline void pup(int p){ tr[p] = tr[ls] + tr[rs]; }
inline void ptag(int p,ll v){
tag[p] += v;
tr[p].iter -= v;
tr[p].lm.add(v),tr[p].rm.add(v),tr[p].tot.add(v),tr[p].sum.add(v);
}
inline void pdown(int p){
if(tag[p]){
ptag(ls, tag[p]), ptag(rs, tag[p]);
tag[p] = 0;
}
}
void build(int p,int l,int r){
if(l == r){
Func tmp = {1, a[l]};
tr[p] = {tmp, tmp, tmp, tmp, inf};
return ;
}
int mid = (l + r) >> 1;
build(ls, l, mid), build(rs, mid+1, r);
pup(p);
}
void defeat(int p,int l,int r,ll v){
if(v > tr[p].iter){
int mid = (l + r) >> 1;
defeat(ls, l, mid, tag[p]+v);
defeat(rs, mid+1, r, tag[p]+v);
tag[p] = 0, pup(p);
}else ptag(p, v);
}
void upd(int p,int l,int r,int L,int R,int k){
if(L <= l && r <= R)return defeat(p, l, r, k);
pdown(p);
int mid = (l + r) >> 1;
if(L <= mid)upd(ls, l, mid, L, R, k);
if(mid < R)upd(rs, mid+1, r, L, R, k);
pup(p);
}
node qry(int p,int l,int r,int L,int R){
if(L <= l && r <= R)return tr[p];
pdown(p); int mid = (l + r) >> 1;
if(R <= mid)return qry(ls, l, mid, L, R);
if(L > mid)return qry(rs, mid+1, r, L, R);
return qry(ls, l, mid, L, R) + qry(rs, mid+1, r, L, R);
}
#undef ls
#undef rs
}using namespace KTT;
int main(){
read(n), read(qcnt);
rep(i, 1, n)read(a[i]);
build(1, 1, n);
int op, l, r, v;
while(qcnt--){
read(op);
if(op == 1){
read(l, r, v);
upd(1, 1, n, l, r, v);
}else{
read(l, r);
printf("%lld\n",max(0ll,qry(1, 1, n, l, r).tot.b));
}
}
return 0;
}
KTT+吉司机
//https://www.luogu.com.cn/problem/P6792
#include<bits/stdc++.h>
#define rep(i, l, r) for(int i(l);i<=(r);++i)
#define per(i, r, l) for(int i(r);i>=(l);--i)
using namespace std;
namespace IO{
template <typename T>
inline void read(T &x){
x = 0;
static char c;
static bool f;
c = getchar(), f = 0;
while(c<'0'||c>'9'){ if(c == '-')f = 1; c = getchar(); }
while('0'<=c&&c<='9')x = (x << 3) + (x << 1) + (c ^ 48), c = getchar();
x = f ? -x : x;
}
template <typename T,typename ...Types>
inline void read(T &x, Types &...y){
read(x), read(y...);
}
}using namespace IO;
using ll = long long;
const int N = 4e5 + 10;
const ll inf = 1e15;
template <typename T>
inline void ckmin(T &x, T y){ (x > y) && (x = y); }
int n,a[N],qcnt;
namespace KTT{
struct Func{
int k; ll b;
inline friend Func operator +(const Func &a,const Func &b){ return (Func){a.k+b.k,a.b+b.b}; }
inline void add(ll v){ b += k * v; }
inline void set(){ k = 0; }
};
inline pair<Func, ll> max(Func a, Func b){
if(a.k < b.k || (a.k == b.k && a.b < b.b))swap(a, b);
if(a.b >= b.b)return {a, inf};
return {b, (b.b-a.b)/(a.k-b.k)};
}
struct node{
Func lm, rm, tot, sum;
ll iter;//yu zhi
inline friend node operator +(const node &a,const node &b){
node res; pair<Func, ll> tmp;
res.iter = min(a.iter, b.iter);
tmp = max(a.lm, b.lm + a.sum);
res.lm = tmp.first, ckmin(res.iter, tmp.second);
tmp = max(b.rm, a.rm + b.sum);
res.rm = tmp.first, ckmin(res.iter, tmp.second);
tmp = max(a.tot, b.tot);
ckmin(res.iter, tmp.second);
tmp = max(tmp.first, a.rm + b.lm);
ckmin(res.iter, tmp.second);
res.tot = tmp.first;
res.sum = a.sum + b.sum;
return res;
}
inline node set(){
node a = *this;
a.lm.set(), a.rm.set(), a.tot.set(), a.sum.set();
return a;
}
}tr[N << 2];
ll tag[N << 2], mn[N << 2], se[N << 2];
#define ls (p << 1)
#define rs (p << 1 | 1)
inline void pup(int p){
if(mn[ls] == mn[rs]){
mn[p] = mn[ls];
se[p] = min(se[ls], se[rs]);
tr[p] = tr[ls] + tr[rs];
}
if(mn[ls] < mn[rs]){
mn[p] = mn[ls];
se[p] = min(se[ls], mn[rs]);
tr[p] = tr[ls] + tr[rs].set();
}
if(mn[ls] > mn[rs]){
mn[p] = mn[rs];
se[p] = min(mn[ls], se[rs]);
tr[p] = tr[ls].set() + tr[rs];
}
}
inline void ptag(int p,ll v){
if(v <= mn[p])return ;
ll w = v - mn[p];
mn[p] = v;
tag[p] = std::max(tag[p], v);
tr[p].iter -= w;
tr[p].lm.add(w),tr[p].rm.add(w),tr[p].tot.add(w),tr[p].sum.add(w);
}
inline void pdown(int p){
if(tag[p] != -inf){
ptag(ls, tag[p]), ptag(rs, tag[p]);
tag[p] = -inf;
}
}
void build(int p,int l,int r){
tag[p] = -inf;
if(l == r){
Func tmp = {1, a[l]};
tr[p] = {tmp, tmp, tmp, tmp, inf};
mn[p] = a[l], se[p] = inf;
return ;
}
int mid = (l + r) >> 1;
build(ls, l, mid), build(rs, mid+1, r);
pup(p);
}
void defeat(int p,int l,int r,ll v){
tag[p] = std::max(tag[p], v);
if(v - mn[p] > tr[p].iter){
int mid = (l + r) >> 1;
defeat(ls, l, mid, v);
defeat(rs, mid+1, r, v);
pup(p);
}else ptag(p, v);
}
void upd(int p,int l,int r,int L,int R,int k){
if(mn[p] >= k)return ;
if(L <= l && r <= R && k < se[p])return defeat(p, l, r, k);
pdown(p);
int mid = (l + r) >> 1;
if(L <= mid)upd(ls, l, mid, L, R, k);
if(mid < R)upd(rs, mid+1, r, L, R, k);
pup(p);
}
node qry(int p,int l,int r,int L,int R){
if(L <= l && r <= R)return tr[p];
pdown(p); int mid = (l + r) >> 1;
if(R <= mid)return qry(ls, l, mid, L, R);
if(L > mid)return qry(rs, mid+1, r, L, R);
return qry(ls, l, mid, L, R) + qry(rs, mid+1, r, L, R);
}
#undef ls
#undef rs
}using namespace KTT;
int main(){
read(n), read(qcnt);
rep(i, 1, n)read(a[i]);
build(1, 1, n);
int op, l, r, v;
while(qcnt--){
read(op);
if(!op){
read(l, r, v);
upd(1, 1, n, l, r, v);
}else{
read(l, r);
printf("%lld\n",max(0ll,qry(1, 1, n, l, r).tot.b));
}
}
return 0;
}
平衡树
FHQ-Treap
维护区间reverse和01flip
// 203 contest 1158 T4 魔塔
#include<bits/stdc++.h>
#define rep(i, l, r) for(int i(l);i<=(r);++i)
#define per(i, r, l) for(int i(r);i>=(l);--i)
#define print(a) cerr<<#a"="<<(a)<<endl
#define debug() cerr<<"\n--------\n"
#define Pline cerr<<"Line:"<<__LINE__<<'\n'
using namespace std;
namespace IO{
template <typename T>
inline void read(T &x){
x = 0;
static char c;
static bool f;
c = getchar(), f = 0;
while(c<'0'||c>'9'){ if(c == '-')f = 1; c = getchar(); }
while('0'<=c&&c<='9')x = (x << 3) + (x << 1) + (c ^ 48), c = getchar();
x = f ? -x : x;
}
template <typename T,typename ...Types>
inline void read(T &x, Types &...y){
read(x), read(y...);
}
}using namespace IO;
const int N = 2e5 + 10;
int n, qcnt;
char s[N];
mt19937 rng(random_device{}());
using pii = pair<int,int>;
#define fi first
#define se second
#define MP make_pair
struct Info{
int sum, lmax, lmin, rmax, rmin;
Info(int _sum = 0, int _lmax = 0, int _lmin = 0, int _rmax = 0, int _rmin = 0):sum(_sum),lmax(_lmax),lmin(_lmin),rmax(_rmax),rmin(_rmin){};
Info friend operator +(const Info &a,const Info &b){
return Info(
a.sum + b.sum,
max(a.lmax, a.sum + b.lmax),
min(a.lmin, a.sum + b.lmin),
max(a.rmax + b.sum, b.rmax),
min(a.rmin + b.sum, b.rmin)
);
}
};
Info tr[N];
int tot, val[N], rt;
int ch[N][2], siz[N];
int tag1[N], tag2[N];
unsigned int pri[N];
inline int New(int v){
int p = ++tot;
tr[p] = Info(v, v, v, v, v);
val[p] = v, ch[p][0] = ch[p][1] = 0, siz[p] = 1;
tag1[p] = tag2[p] = 0;
pri[p] = rng();
return p;
}
inline void pup(int p){
siz[p] = 1;
tr[p] = Info(val[p], val[p], val[p], val[p], val[p]);
if(ch[p][0])tr[p] = tr[ch[p][0]] + tr[p], siz[p] += siz[ch[p][0]];
if(ch[p][1])tr[p] = tr[p] + tr[ch[p][1]], siz[p] += siz[ch[p][1]];
}
inline void Tag1(int p){
tag1[p] ^= 1;
swap(tr[p].lmax, tr[p].rmax);
swap(tr[p].lmin, tr[p].rmin);
swap(ch[p][0], ch[p][1]);
}
inline void Tag2(int p){
tag2[p] ^= 1;
val[p] *= -1;
tr[p].sum *= -1, tr[p].lmax *= -1, tr[p].lmin *= -1, tr[p].rmax *= -1, tr[p].rmin *= -1;
swap(tr[p].lmax, tr[p].lmin);
swap(tr[p].rmax, tr[p].rmin);
}
inline void pdown(int p){
if(tag1[p]){
if(ch[p][0])Tag1(ch[p][0]);
if(ch[p][1])Tag1(ch[p][1]);
tag1[p] = 0;
}
if(tag2[p]){
if(ch[p][0])Tag2(ch[p][0]);
if(ch[p][1])Tag2(ch[p][1]);
tag2[p] = 0;
}
}
pii split(int u,int val){
if(!u)return {0, 0};
pdown(u);
if(siz[ch[u][0]] >= val){
pii tmp = split(ch[u][0], val);
ch[u][0] = tmp.se;
return pup(u), MP(tmp.fi, u);
}else{
pii tmp = split(ch[u][1], val-siz[ch[u][0]]-1);
ch[u][1] = tmp.fi;
return pup(u), MP(u, tmp.se);
}
}
int qval(int u,int sz){
pdown(u);
if(siz[ch[u][0]] >= sz)return qval(ch[u][0], sz);
sz -= siz[ch[u][0]] + 1;
if(!sz)return val[u];
return qval(ch[u][1], sz);
}
int qpos(int u,int k){
pdown(u);
// print(k),print(tr[ch[u][0]].lmin),print(tr[ch[u][1]].lmax);
if(tr[ch[u][0]].lmin <= k && k <= tr[ch[u][0]].lmax)return qpos(ch[u][0], k);
k -= tr[ch[u][0]].sum + val[u];
if(!k)return siz[ch[u][0]] + 1;
return siz[ch[u][0]] + 1 + qpos(ch[u][1], k);
}
int merge(int p,int q){
if(!p || !q)return p | q;
if(pri[p] < pri[q])return pdown(p), ch[p][1] = merge(ch[p][1], q), pup(p), p;
else return pdown(q), ch[q][0] = merge(p, ch[q][0]), pup(q), q;
}
void output(int u){
cerr<<u<<":\n";
if(ch[u][0])cerr<<u << " ls->",output(ch[u][0]);
if(ch[u][1])cerr<<u << " rs->",output(ch[u][1]);
}
void solve(){
read(n, qcnt);
scanf("%s",s+1);
rt = tot = 0;
rep(i, 1, n)rt = merge(rt, New(s[i] == '1' ? 1 : -1));
int op, x, y;
while(qcnt--){
read(op, x, y);
if(op == 2){
pii tmp = split(rt, y);
pii cur = split(tmp.fi, x-1);
Tag1(cur.se);
rt = merge(merge(cur.fi, cur.se), tmp.se);
}else if(op == 3){
pii tmp = split(rt, y);
pii cur = split(tmp.fi, x-1);
Tag2(cur.se);
rt = merge(merge(cur.fi, cur.se), tmp.se);
}else{
int v = qval(rt, x);
if(v == 1){
if(y == 1){
printf("%d\n",x);
continue;
}
pii tmp = split(rt, x-1);
if(!tmp.se || tr[tmp.se].lmin > y - 1 || tr[tmp.se].lmax < y - 1){
rt = merge(tmp.fi, tmp.se), puts("-1");
continue;
}
int ps = qpos(tmp.se, y-1);
pii t2 = split(tmp.se, ps);
if(!t2.se || tr[t2.se].lmin > 1 || tr[t2.se].lmax < 1){
rt = merge(tmp.fi, merge(t2.fi, t2.se)), puts("-1");
continue;
}
int ans = qpos(t2.se, 1);
printf("%d\n",siz[tmp.fi] + siz[t2.fi] + ans);
rt = merge(tmp.fi, merge(t2.fi, t2.se));
}else{
if(y == -1){
printf("%d\n",x);
continue;
}
pii tmp = split(rt, x-1);
if(!tmp.se || tr[tmp.se].lmin > y + 1 || tr[tmp.se].lmax < y + 1){
rt = merge(tmp.fi, tmp.se), puts("-1");
continue;
}
int ps = qpos(tmp.se, y+1);
pii t2 = split(tmp.se, ps);
if(!t2.se || tr[t2.se].lmin > -1 || tr[t2.se].lmax < -1){
rt = merge(tmp.fi, merge(t2.fi, t2.se)), puts("-1");
continue;
}
int ans = qpos(t2.se, -1);
printf("%d\n",siz[tmp.fi] + siz[t2.fi] + ans);
rt = merge(tmp.fi, merge(t2.fi, t2.se));
}
}
}
}
int main(){
freopen("magictower.in","r",stdin);
freopen("magictower.out","w",stdout);
int T; read(T);
while(T--)
solve();
return 0;
}
动态开点 n 个 Treap
//203 contest 1151 T4
#include<bits/stdc++.h>
#define rep(i, l, r) for(int i(l);i<=(r);++i)
#define per(i, r, l) for(int i(r);i>=(l);--i)
#define print(a) cerr<<#a"="<<(a)<<endl
using namespace std;
template <typename T>
inline void read(T &x){
x = 0;
static char c;
static bool f;
c = getchar(), f = 0;
while(c<'0'||c>'9'){ if(c == '-')f = 1; c = getchar(); }
while('0'<=c&&c<='9')x = (x << 3) + (x << 1) + (c ^ 48), c = getchar();
x = f ? -x : x;
}
mt19937 rnd(random_device{}());
using pii = pair<int,int>;
#define fi first
#define se second
const int N = 3e5 + 10;
int n,m,k;
int a[N], b[N];
struct FHQ{
int rt[N], tot;
struct node{
int fa,ls,rs;
unsigned lzx;
int x, y;
node(int x = 0, int y = 0):fa(0),ls(0),rs(0),lzx(rnd()),x(x),y(y){}
}tr[3 * N];
int &operator [](const int i){ return rt[i]; }
int st[N << 1], top;
map<int,int> mp[N];
inline int Newnode(int x = 0, int y = 0){
int p = (top ? st[top--] : ++tot);
return tr[p] = node(x, y), mp[y][x] = p;
}
inline void del(int p){ mp[tr[p].y].erase(tr[p].x), st[++top] = p; }
void init(){
tot = 0, top = 0;
rep(i, 1, n)rt[i] = Newnode(1, i);
}
#define ls(p) (tr[p].ls)
#define rs(p) (tr[p].rs)
#define fa(p) (tr[p].fa)
inline void pup(int p){
fa(p) = 0;
if(ls(p))fa(ls(p)) = p;
if(rs(p))fa(rs(p)) = p;
}
int merge(int p,int q){
if(!p || !q)return p | q;
if(tr[p].lzx > tr[q].lzx)return rs(p) = merge(rs(p), q), pup(p), p;
else return ls(q) = merge(p, ls(q)), pup(q), q;
}
pii split(int p,int x){// <= x
if(!p)return {0, 0};
if(tr[p].x <= x){
pii tmp = split(rs(p), x);
rs(p) = tmp.fi, pup(p);
return {p, tmp.se};
}else{
pii tmp = split(ls(p), x);
ls(p) = tmp.se, pup(p);
return {tmp.fi, p};
}
}
inline int getid(int x,int y){
int p = (--mp[y].upper_bound(x))->second;
while(fa(p))p = fa(p);
while(ls(p))p = ls(p);
return tr[p].y;
}
void insert(int id,int x,int y){
int p = getid(id, x);
pii t1 = split(rt[p], id);
int pR = merge(Newnode(id+1, x), t1.se);
int q = getid(id, y);
pii t2 = split(rt[q], id);
int qR = merge(Newnode(id+1, y), t2.se);
rt[p] = merge(t1.fi, qR), rt[q] = merge(t2.fi, pR);
}
void erase(int id,int x,int y){
int p = getid(id, x);
// print(p);
pii t1 = split(rt[p], id+1);
pii t2 = split(t1.fi, id);
del(t2.se);
// cerr<<t2.fi<<' '<<t2.se<<' '<<t1.se<<">>>>\n";
// t2.fi t2.se t1.se
int q = getid(id, y);
pii t3 = split(rt[q], id+1);
pii t4 = split(t3.fi, id);
// cerr<<t4.fi<<' '<<t4.se<<' '<<t3.se<<"<<<<\n";
// t4.fi t4.se t3.se
del(t4.se);
rt[p] = merge(t2.fi, t3.se), rt[q] = merge(t4.fi, t1.se);
// cerr << rt[p] << ' ' << rt[q] << "<<<<\n";
}
inline int Rson(int p){
while(rs(p))p = rs(p);
return p;
}
inline int qry(int x,int l,int r){
int p = getid(l, x);
pii t = split(rt[p], r+1);
int res = tr[Rson(t.fi)].y;
rt[p] = merge(t.fi, t.se);
return res;
}
#undef ls
#undef rs
#undef fa
}tr;
namespace sub3{
struct node{
int ts[6];
node(){ rep(i, 1, n)ts[i] = i; }
inline node friend operator +(const node &a,const node &b){
node res;
rep(i, 1, n)res[i] = b[a[i]];
return res;
}
inline void init(int id){
rep(i, 1, n)ts[i] = i;
ts[a[id]] = b[id];
ts[b[id]] = a[id];
}
int & operator [](const int i){ return ts[i]; }
const int & operator [](const int i)const{ return ts[i]; }
}tr[N << 2];
#define ls (p << 1)
#define rs (p << 1 | 1)
#define mid ((l + r) >> 1)
inline void pup(int p){ tr[p] = tr[ls] + tr[rs]; }
void upd(int p,int l,int r,int x){
if(l == r)return tr[p].init(x),void();
x <= mid ? upd(ls, l, mid, x) : upd(rs, mid+1, r, x);
pup(p);
}
void build(int p,int l,int r){
if(l == r)return tr[p].init(l),void();
build(ls, l, mid), build(rs, mid+1, r);
pup(p);
}
node qry(int p,int l,int r,int L,int R){
if(L <= l && r <= R)return tr[p];
if(R <= mid)return qry(ls, l, mid, L, R);
if(mid < L)return qry(rs, mid+1, r, L, R);
return qry(ls, l, mid, L, R) + qry(rs, mid+1, r, L, R);
}
void solve(){
build(1, 1, m);
char str[4];
int x, y, z;
while(k--){
scanf("%s",str);
read(x), read(y), read(z);
if(str[0] == 'A'){
a[x] = y, b[x] = z;
upd(1, 1, m, x);
}else{
node res = qry(1, 1, m, y, z);
printf("%d\n",res[x]);
}
}
}
#undef ls
#undef rs
#undef mid
}
int main(){
freopen("hats.in","r",stdin);
freopen("hats.out","w",stdout);
read(n),read(m),read(k);
tr.init();
rep(i, 1, m)read(a[i]), read(b[i]), tr.insert(i, a[i], b[i]);
if(n <= 5)
return sub3::solve(),0;
char str[4];
int x, y, z;
while(k--){
scanf("%s",str);
read(x), read(y), read(z);
if(*str == 'A'){
tr.erase(x, a[x], b[x]);
a[x] = y, b[x] = z;
tr.insert(x, a[x], b[x]);
}else{
printf("%d\n",tr.qry(x, y, z));
}
}
return 0;
}

浙公网安备 33010602011771号