【学习笔记】数据结构全家桶
前言
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;
}

浙公网安备 33010602011771号