#pragma once
template<typenameT,T(*add)(T,T),T(*sub)(T,T),T(*mul)(T,longlong)>structLinkCutForSubtreeNode{usingNode=LinkCutForSubtreeNode;usingPtr=LinkCutForSubtreeNode*;Ptrl,r,p;Tkey,sum,lazy,cancel,subsum;intcnt,subcnt;boolrev;LinkCutForSubtreeNode(constT&t=T()):l(),r(),p(),key(t),sum(t),lazy(T()),cancel(T()),subsum(T()),cnt(1),subcnt(0),rev(false){}voidmake_normal(Ptrother){subsum=add(subsum,other->sum);subcnt+=other->cnt;}voidmake_prefer(Ptrother){subsum=sub(subsum,other->sum);subcnt-=other->cnt;}voidmerge(Ptrn1,Ptrn2){sum=add(add(n1?n1->sum:T(),key),add(subsum,n2?n2->sum:T()));cnt=1+(n1?n1->cnt:0)+(n2?n2->cnt:0)+subcnt;if(n1)n1->cancel=lazy;if(n2)n2->cancel=lazy;}voidapply(constT&add_val){key=add(key,add_val);sum=add(sum,mul(add_val,cnt));lazy=add(lazy,add_val);subsum=add(subsum,mul(add_val,subcnt));}voidfetch(){if(!p)return;apply(p->lazy-cancel);cancel=p->lazy;}};template<typenameT,T(*add)(T,T),T(*sub)(T,T),T(*mul)(T,longlong)>structLinkCutTreeSubtreeQuery{usingNode=LinkCutForSubtreeNode<T,add,sub,mul>;usingPtr=Node*;voidpush_rev(Ptrt){if(!t)return;if(t->rev){if(t->l)toggle(t->l);if(t->r)toggle(t->r);t->rev=false;}}voidpush(Ptrt){if(!t)return;if(t->rev){if(t->l)toggle(t->l);if(t->r)toggle(t->r);t->rev=false;}if(t->l)t->l->fetch();if(t->r)t->r->fetch();}Ptrupdate(Ptrt){if(!t)returnt;t->merge(t->l,t->r);returnt;}voidsplay(Ptrt){push(t);while(!is_root(t)){Ptrq=t->p;if(is_root(q)){push_rev(q),push_rev(t);rot(t);}else{Ptrr=q->p;push_rev(r),push_rev(q),push_rev(t);if(pos(q)==pos(t))rot(q),rot(t);elserot(t),rot(t);}}}Ptrexpose(Ptrt){Ptrrp=nullptr;for(Ptrcur=t;cur;cur=cur->p){splay(cur),push(cur);if(cur->r)cur->make_normal(cur->r);if(rp)rp->fetch(),cur->make_prefer(rp);cur->r=rp;rp=cur;}splay(t);returnrp;}voidevert(Ptrt){expose(t);toggle(t);push(t);}voidlink(Ptru,Ptrv){evert(u);expose(v);u->p=v,v->r=u;update(v);}voidcut(Ptru,Ptrv){evert(u);expose(v);v->l=u->p=nullptr;update(v);}voidtoggle(Ptrt){if(!t)return;swap(t->l,t->r);t->rev^=true;}Tget_key(Ptrt){expose(t);returnt->key;}voidset_key(Ptrt,constT&key){expose(t);t->key=key;update(t);}voidsubtree_add(Ptrt,constT&add_val){expose(t);Ptrl=t->l;if(l)t->l=nullptr,update(t);t->apply(add_val);if(l)t->l=l,update(t);}Tsubtree_sum(Ptrt){expose(t);returnadd(t->key,t->subsum);}Ptrget_root(Ptrx){expose(x);while(x->l)this->push(x),x=x->l;returnx;}protected:boolis_root(Ptrt){return!(t->p)||(t->p->l!=t&&t->p->r!=t);}inlineintpos(Ptrt){if(t->p){if(t->p->l==t)return-1;if(t->p->r==t)return1;}return0;}voidrot(Ptrt){Ptrx=t->p,y=x->p;push(x),push(t);if(pos(t)==-1){if((x->l=t->r))t->r->p=x;t->r=x,x->p=t;}else{if((x->r=t->l))t->l->p=x;t->l=x,x->p=t;}Txc=x->cancel;update(x),update(t);t->cancel=xc;if((t->p=y)){if(y->l==x)y->l=t;if(y->r==x)y->r=t;}}};/**
* @brief 部分木加算クエリLink/Cut Tree
*/
#line 2 "lct/link-cut-tree-subtree-add.hpp"
template<typenameT,T(*add)(T,T),T(*sub)(T,T),T(*mul)(T,longlong)>structLinkCutForSubtreeNode{usingNode=LinkCutForSubtreeNode;usingPtr=LinkCutForSubtreeNode*;Ptrl,r,p;Tkey,sum,lazy,cancel,subsum;intcnt,subcnt;boolrev;LinkCutForSubtreeNode(constT&t=T()):l(),r(),p(),key(t),sum(t),lazy(T()),cancel(T()),subsum(T()),cnt(1),subcnt(0),rev(false){}voidmake_normal(Ptrother){subsum=add(subsum,other->sum);subcnt+=other->cnt;}voidmake_prefer(Ptrother){subsum=sub(subsum,other->sum);subcnt-=other->cnt;}voidmerge(Ptrn1,Ptrn2){sum=add(add(n1?n1->sum:T(),key),add(subsum,n2?n2->sum:T()));cnt=1+(n1?n1->cnt:0)+(n2?n2->cnt:0)+subcnt;if(n1)n1->cancel=lazy;if(n2)n2->cancel=lazy;}voidapply(constT&add_val){key=add(key,add_val);sum=add(sum,mul(add_val,cnt));lazy=add(lazy,add_val);subsum=add(subsum,mul(add_val,subcnt));}voidfetch(){if(!p)return;apply(p->lazy-cancel);cancel=p->lazy;}};template<typenameT,T(*add)(T,T),T(*sub)(T,T),T(*mul)(T,longlong)>structLinkCutTreeSubtreeQuery{usingNode=LinkCutForSubtreeNode<T,add,sub,mul>;usingPtr=Node*;voidpush_rev(Ptrt){if(!t)return;if(t->rev){if(t->l)toggle(t->l);if(t->r)toggle(t->r);t->rev=false;}}voidpush(Ptrt){if(!t)return;if(t->rev){if(t->l)toggle(t->l);if(t->r)toggle(t->r);t->rev=false;}if(t->l)t->l->fetch();if(t->r)t->r->fetch();}Ptrupdate(Ptrt){if(!t)returnt;t->merge(t->l,t->r);returnt;}voidsplay(Ptrt){push(t);while(!is_root(t)){Ptrq=t->p;if(is_root(q)){push_rev(q),push_rev(t);rot(t);}else{Ptrr=q->p;push_rev(r),push_rev(q),push_rev(t);if(pos(q)==pos(t))rot(q),rot(t);elserot(t),rot(t);}}}Ptrexpose(Ptrt){Ptrrp=nullptr;for(Ptrcur=t;cur;cur=cur->p){splay(cur),push(cur);if(cur->r)cur->make_normal(cur->r);if(rp)rp->fetch(),cur->make_prefer(rp);cur->r=rp;rp=cur;}splay(t);returnrp;}voidevert(Ptrt){expose(t);toggle(t);push(t);}voidlink(Ptru,Ptrv){evert(u);expose(v);u->p=v,v->r=u;update(v);}voidcut(Ptru,Ptrv){evert(u);expose(v);v->l=u->p=nullptr;update(v);}voidtoggle(Ptrt){if(!t)return;swap(t->l,t->r);t->rev^=true;}Tget_key(Ptrt){expose(t);returnt->key;}voidset_key(Ptrt,constT&key){expose(t);t->key=key;update(t);}voidsubtree_add(Ptrt,constT&add_val){expose(t);Ptrl=t->l;if(l)t->l=nullptr,update(t);t->apply(add_val);if(l)t->l=l,update(t);}Tsubtree_sum(Ptrt){expose(t);returnadd(t->key,t->subsum);}Ptrget_root(Ptrx){expose(x);while(x->l)this->push(x),x=x->l;returnx;}protected:boolis_root(Ptrt){return!(t->p)||(t->p->l!=t&&t->p->r!=t);}inlineintpos(Ptrt){if(t->p){if(t->p->l==t)return-1;if(t->p->r==t)return1;}return0;}voidrot(Ptrt){Ptrx=t->p,y=x->p;push(x),push(t);if(pos(t)==-1){if((x->l=t->r))t->r->p=x;t->r=x,x->p=t;}else{if((x->r=t->l))t->l->p=x;t->l=x,x->p=t;}Txc=x->cancel;update(x),update(t);t->cancel=xc;if((t->p=y)){if(y->l==x)y->l=t;if(y->r==x)y->r=t;}}};/**
* @brief 部分木加算クエリLink/Cut Tree
*/