teamnote history merge

This commit is contained in:
2026-06-03 09:36:52 +09:00
parent f50ed902fe
commit 7176febe54
142 changed files with 13243 additions and 0 deletions

View File

@@ -0,0 +1,278 @@
struct Node
{
Node *p, *l, *r;
int key, cnt;
ll val; ll m, M, sum; ll lazy;
bool flip;
Node(int key, ll val):p(0),l(0), r(0), key(key), cnt(1), val(val), m(val), M(val), sum(val), lazy(0), flip(0){}
void fix()
{
cnt = 1+(l?l->cnt:0)+(r?r->cnt:0);
sum = val+(l?l->sum:0)+(r?r->sum:0);
m = min({val, (l?l->m:inf), (r?r->m:inf)});
M = max({val, (l?l->M:-1), (r?r->M:-1)});
}
void prop()
{
if(flip)
{
swap(l, r);
if(l) l->flip = !l->flip;
if(r) r->flip = !r->flip;
flip = false;
}
if(lazy)
{
val += lazy; sum += cnt * lazy;
if(l) l->lazy += lazy;
if(r) r->lazy += lazy;
lazy = 0;
}
}
} *root;
struct SplayTree
{
Node *root = NULL, *rp = NULL;
SplayTree(){}
SplayTree(Node *rt)
{
if(!rt) return;
root = rt;
rp = rt->p;
}
void mop(Node *node)
{
if(node == root) node->prop();
else mop(node->p);
if(node->l) node->l->prop();
if(node->r) node->r->prop();
}
void rotate(Node *node)
{
if(!root) return;
if(node->p == rp) return;
if(node->p->l == node)
{
Node *p = node->p, *g = p->p;
Node *a = node->l, *b = node->r, *c = p->r;
p->l = b; if(b) b->p = p;
p->r = c; if(c) c->p = p;
node->l = a; if(a) a->p = node;
node->r = p; p->p = node;
node->p = g; if(g) (g->l == p?g->l:g->r) = node;
p->fix(); node->fix();
if(p == root) root = node;
}
else
{
Node *p = node->p, *g = p->p;
Node *a = p->l, *b = node->l, *c = node->r;
p->l = a; if(a) a->p = p;
p->r = b; if(b) b->p = p;
node->l = p; p->p = node;
node->r = c; if(c) c->p = node;
node->p = g; if(g) (g->l == p?g->l:g->r) = node;
p->fix(); node->fix();
if(p == root) root = node;
}
}
void splay(Node* node)
{
if(!root) return;
assert(node); mop(node);
while(node->p != rp)
{
Node *p, *g;
p = node->p; g = p->p;
if(g == rp) rotate(node);
else if((p->l == node) == (g->l == p))
rotate(p), rotate(node);
else rotate(node), rotate(node);
}
root = node;
}
Node* insert(int key, ll val)
{
if(!root)
{
root = new Node(key, val);
return root;
}
else
{
Node *now = root;
while(true)
{
if(now->key == key) return NULL;
else if(now->key > key)
{
if(!now->l) break;
now = now->l;
}
else
{
if(!now->r) break;
now = now->r;
}
}
Node *ret;
if(now->key > key)
{
ret = now->l = new Node(key, val);
now->l->p = now;
splay(now->l);
}
else
{
ret = now->r = new Node(key, val);
now->r->p = now;
splay(now->r);
}
return ret;
}
}
/*Node* find(int key)
{
Node* now = root;
if(!now) return NULL;
while(true)
{
if(key == now->key) break;
else if(key < now->key)
{
if(!now->l) break;
now = now->l;
}
else
{
if(!now->r) break;
now = now->r;
}
}
splay(now);
return key == now->key?now:NULL;
}
void erase(int key)
{
if(!find(key)) return;
if(root->l and root->r)
{
Node* e = root;
root = root->l; root->p = NULL;
Node* now = root;
while(now->r) now = now->r;
now->r = e->r;
e->r->p = now;
splay(now);
delete e;
}
else if(root->l)
{
Node* now = root;
root = root->l; root->p = NULL;
delete now;
}
else if(root->r)
{
Node* now = root;
root = root->r; root->p = NULL;
delete now;
}
else
{
delete root;
root = NULL;
}
}*/
Node* find_kth(int k) // 0-indexed
{
assert(root);
assert(root->cnt > k);
Node *now = root; now->prop();
while(true)
{
while(now->l and now->l->cnt > k) now = now->l, now->prop();
k -= now->l?now->l->cnt:0;
if(k == 0) break;
k--; now = now->r;
now->prop();
}
splay(now);
return now;
}
Node* gather(int s, int e)
{
find_kth(e+1);
SplayTree(root->l).find_kth(s-1);
assert(root->l->r);
return root->l->r;
}
void update(int i, int j, ll val)
{
Node *node = gather(i, j);
node->lazy += val; node->prop();
node->p->fix(); node->p->p->fix();
}
void reverse(int i, int j)
{
Node *node = gather(i, j);
node->flip = !node->flip;
}
void p_vals(int n){p_vals(root, 0, false, n);}
void p_vals(Node* node, ll lz, bool flip, int n)
{
lz += node->lazy; flip ^= node->flip;
if(!flip)
{
if(node->l) p_vals(node->l, lz, flip, n);
if(!(node->key == 0 or node->key == n+1)) printf("%lld ", node->val+lz);
if(node->r) p_vals(node->r, lz, flip, n);
}
else
{
if(node->r) p_vals(node->r, lz, flip, n);
if(!(node->key == 0 or node->key == n+1)) printf("%lld ", node->val+lz);
if(node->l) p_vals(node->l, lz, flip, n);
}
}
};