#line 2 "cpplib/util/template.hpp" #pragma GCC optimize("Ofast") #pragma GCC optimize("unroll-loops") #pragma GCC target("avx2") #include using namespace std; struct __INIT__{__INIT__(){cin.tie(0);ios::sync_with_stdio(false);cout< vec; typedef vector> mat; typedef vector>> mat3; typedef vector svec; typedef vector> smat; templateusing V=vector; templateusing VV=V>; templateinline void output(T t){bool f=0;for(auto i:t){cout<<(f?" ":"")<inline void output2(T t){for(auto i:t)output(i);} templateinline void debug(T t){bool f=0;for(auto i:t){cerr<<(f?" ":"")<inline void debug2(T t){for(auto i:t)debug(i);} #define loop(n) for(long long _=0;_<(long long)(n);++_) #define _overload4(_1,_2,_3,_4,name,...) name #define __rep(i,a) repi(i,0,a,1) #define _rep(i,a,b) repi(i,a,b,1) #define repi(i,a,b,c) for(long long i=(long long)(a);i<(long long)(b);i+=c) #define rep(...) _overload4(__VA_ARGS__,repi,_rep,__rep)(__VA_ARGS__) #define _overload3_rev(_1,_2,_3,name,...) name #define _rep_rev(i,a) repi_rev(i,0,a) #define repi_rev(i,a,b) for(long long i=(long long)(b)-1;i>=(long long)(a);--i) #define rrep(...) _overload3_rev(__VA_ARGS__,repi_rev,_rep_rev)(__VA_ARGS__) // #define rep(i,...) for(auto i:range(__VA_ARGS__)) // #define rrep(i,...) for(auto i:reversed(range(__VA_ARGS__))) // #define repi(i,a,b) for(lint i=lint(a);i<(lint)(b);++i) // #define rrepi(i,a,b) for(lint i=lint(b)-1;i>=lint(a);--i) // #define irep(i) for(lint i=0;;++i) // inline vector range(long long n){if(n<=0)return vector();vectorv(n);iota(v.begin(),v.end(),0LL);return v;} // inline vector range(long long a,long long b){if(b<=a)return vector();vectorv(b-a);iota(v.begin(),v.end(),a);return v;} // inline vector range(long long a,long long b,long long c){if((b-a+c-1)/c<=0)return vector();vectorv((b-a+c-1)/c);for(int i=0;i<(int)v.size();++i)v[i]=i?v[i-1]+c:a;return v;} // templateinline T reversed(T v){reverse(v.begin(),v.end());return v;} #define all(n) begin(n),end(n) templatebool chmin(T& s,const E& t){bool res=s>t;s=min(s,t);return res;} templatebool chmax(T& s,const E& t){bool res=s(s,t);return res;} const string ds="DRUL"; const vector dx={1,0,-1,0,1,1,-1,-1}; const vector dy={0,1,0,-1,1,-1,1,-1}; #define SUM(v) accumulate(all(v),0LL) #if __cplusplus>=201703L templateauto make_vector(T x,int arg,Args ...args){if constexpr(sizeof...(args)==0)return vector(arg,x);else return vector(arg,make_vector(x,args...));} #endif #define extrep(v,...) for(auto v:__MAKE_MAT__({__VA_ARGS__})) #define bit(n,a) ((n>>a)&1) vector> __MAKE_MAT__(vector v){if(v.empty())return vector>(1,vector());long long n=v.back();v.pop_back();vector> ret;vector> tmp=__MAKE_MAT__(v);for(auto e:tmp)for(long long i=0;i>; templateusing graph_w=vector>>; templateostream& operator<<(ostream& out,pairv){out<<"("<=201703L constexpr inline long long powll(long long a,long long b){long long res=1;while(b--)res*=a;return res;} #endif templatepair& operator+=(pair&s,const pair&t){s.first+=t.first;s.second+=t.second;return s;} templatepair& operator-=(pair&s,const pair&t){s.first-=t.first;s.second-=t.second;return s;} templatepair operator+(const pair&s,const pair&t){auto res=s;return res+=t;} templatepair operator-(const pair&s,const pair&t){auto res=s;return res-=t;} // 128*1024*1024 #define BEGIN_STACK_EXTEND(size) void * stack_extend_memory_ = malloc(size);void * stack_extend_origin_memory_;char * stack_extend_dummy_memory_ = (char*)alloca((1+(int)(((long long)stack_extend_memory_)&127))*16);*stack_extend_dummy_memory_ = 0;asm volatile("mov %%rsp, %%rbx\nmov %%rax, %%rsp":"=b"(stack_extend_origin_memory_):"a"((char*)stack_extend_memory_+(size)-1024)); #define END_STACK_EXTEND asm volatile("mov %%rax, %%rsp"::"a"(stack_extend_origin_memory_));free(stack_extend_memory_); #line 2 "main.cpp" template class toptree{ class rake_tree{ struct node; using np=node*; struct node{ unsigned long key,l,r; T val,sum; // E lazy; bool rev=0; int cnt=1,dep=0; static const node* nil; np ch[2]={}; np p=0; node(unsigned long key,T val):key(key),l(key),r(key),val(val),sum(val){} bool is_root() { return !p||(p->ch[0]!=this&&p->ch[1]!=this); } }; Rake rake; T et; np root=nullptr; inline int count(np t){return t?t->cnt:0;} inline int depth(np t){return t?t->dep:0;} np update(np t){ if(!t)return t; t->cnt=count(t->ch[0])+1+count(t->ch[1]); t->dep=max(depth(t->ch[0]),depth(t->ch[1]))+1; t->l=t->ch[0]?t->ch[0]->l:t->l; t->r=t->ch[1]?t->ch[1]->r:t->r; t->sum=rake(rake(t->ch[0]?t->ch[0]->sum:et,t->val),t->ch[1]?t->ch[1]->sum:et); return t; } void rot(np t,bool b){ np x=t->p,y=x->p; if((x->ch[1-b]=t->ch[b]))t->ch[b]->p=x; t->ch[b]=x,x->p=t; update(x);update(t); if((t->p=y)){ if(y->ch[0]==x)y->ch[0]=t; if(y->ch[1]==x)y->ch[1]=t; update(y); } } void push(np t){ // if(t->lazy!=ee){ // if(t->ch[0])propagate(t->ch[0],t->lazy); // if(t->ch[1])propagate(t->ch[1],t->lazy); // t->lazy=ee; // } // if(t->rev){ // if(t->ch[0])toggle(t->ch[0]); // if(t->ch[1])toggle(t->ch[1]); // t->rev=0; // } } np splay(np t){ push(t); while(!t->is_root()){ np q=t->p; if(q->is_root()){ push(q), push(t); rot(t,q->ch[0]==t); }else{ np r=q->p; push(r), push(q), push(t); bool b=r->ch[0]==q; if(q->ch[1-b]==t)rot(q,b),rot(t,b); else rot(t,1-b),rot(t,b); } } return t; } // int lower_bound(T val,np t){ // if(!t)return 0; // bool b=val>t->val; // return(b?count(t->ch[0])+1:0)+lower_bound(val,t->ch[b]); // } // int upper_bound(T val,np t){ // if(!t)return 0; // bool b=val>=t->val; // return(b?count(t->ch[0])+1:0)+upper_bound(val,t->ch[b]); // } // T find_by_order(T idx,np t){ // if(idx==count(t->ch[0]))return t->val; // bool b=idx>count(t->ch[0]); // return find_by_order(idx-(b?count(t->ch[0])+1:0),t->ch[b]); // } public: rake_tree(Rake rake,T et):rake(rake),et(et){} std::pair split(np t,unsigned long key){ if(!t)return make_pair(nullptr,nullptr); bool b=key>t->key; auto s=split(t->ch[b],key); if(t->ch[b])t->ch[b]->p=0; t->ch[b]=b?s.first:s.second; if(t->ch[b])t->ch[b]->p=t; return b?make_pair(update(t),s.second):make_pair(s.first,update(t)); } std::pair split(unsigned long key){ return split(root,key); } np merge(np s,np t){ if(!s)return t; if(!t)return s; while(s->ch[1])s=s->ch[1]; splay(s);splay(t); s->ch[1]=t; t->p=s; update(s); return s; } void insert(unsigned long key,T val){ auto [s,t]=split(key); root=merge(s,merge(new node(key,val),t)); } void erase(unsigned long key){ auto [s,t]=split(key); while(t->ch[0])t=t->ch[0]; splay(t); assert(t->key==key); if(t->ch[1])t->ch[1]->p=0; root=merge(s,t->ch[1]); delete(t); } rake_tree(T et,Rake rake):et(et),rake(rake){} inline int size(){return count(root);} // inline int count(T val){return upper_bound(val,root)-lower_bound(val,root);} // inline int count(int l,int r){return lower_bound(r,root)-lower_bound(l,root);} // inline T sum(int l,int r){return sum(l,r,root);} inline T all_sum(){return root?root->sum:et;} //0-indexでidx番目 // inline T operator[](T idx){return find_by_order(idx,root);} // //x未満の個数/s[lower_bound(x)]はx以上最小の値 // inline int lower_bound(T x){return lower_bound(x,root);} // //x以下の個数/s[upper_bound(x)]はxより大きい最小の値 // inline int upper_bound(T x){return upper_bound(x,root);} }; public: struct node; using np=node*; struct node{ np ch[2]={}; np p=0; int key; unsigned long id,id_sum,rake_node_id_sum=0; T val,path_sum,subtree_sum,subtree_sum2,subtree_sum_rev,subtree_sum2_rev; rake_tree rake_node; bool rev=0; // E lazy=ee; int sz=1; // node(){} inline unsigned long rnd() { static unsigned long x=123456789, y=362436069, z=521288629, w=88675123; unsigned long t=(x^(x<<11)); x=y; y=z; z=w; return ( w=(w^(w>>19))^(t^(t>>8)) ); } node(unsigned long key,T et,Rake rake):key(key),val(et),path_sum(et),subtree_sum(et),subtree_sum2(et),subtree_sum_rev(et),subtree_sum2_rev(et),rake_node(rake,et){ id=id_sum=rnd(); } bool is_root(){ return !p||(p->ch[0]!=this&&p->ch[1]!=this); } }; std::vectorp; Compress compress; Rake rake; T et; E ee; int size(np t){return t?t->sz:0;} void update(np t){ push(t); t->sz=size(t->ch[0])+1+size(t->ch[1]); // t->l=t->ch[0]?t->ch[0]->l:t->l; // t->r=t->ch[1]?t->ch[1]->r:t->r; t->id_sum=(t->id^(t->ch[0]?t->ch[0]->id_sum:0)^(t->ch[1]?t->ch[1]->id_sum:0)^(t->rake_node_id_sum)); // subtree_sum は親が t, subtree_sum2 は親がt->ch[0]->ch[0]->... // t->path_sum=compress(t->ch[0]?t->ch[0]->path_sum:et,compress(t->val,t->ch[1]?t->ch[1]->path_sum:et)); t->subtree_sum=compress(t->val,rake(t->rake_node.all_sum(),t->ch[1]?t->ch[1]->subtree_sum2:et)); t->subtree_sum2=compress(t->ch[0]?t->ch[0]->subtree_sum2:et,t->subtree_sum); t->subtree_sum_rev=compress(t->val,rake(t->rake_node.all_sum(),t->ch[0]?t->ch[0]->subtree_sum2_rev:et)); t->subtree_sum2_rev=compress(t->ch[1]?t->ch[1]->subtree_sum2_rev:et,t->subtree_sum_rev); } void rot(np t,bool b){ np x=t->p,y=x->p; push(x), push(t); if((x->ch[1-b]=t->ch[b]))t->ch[b]->p=x; t->ch[b]=x,x->p=t; update(x);update(t); if((t->p=y)){ if(y->ch[0]==x)y->ch[0]=t; if(y->ch[1]==x)y->ch[1]=t; update(y); } } void splay(np t){ push(t); while(!t->is_root()){ np q=t->p; if(q->is_root()){ push(q), push(t); rot(t,q->ch[0]==t); }else{ np r=q->p; push(r), push(q), push(t); bool b=r->ch[0]==q; if(q->ch[1-b]==t)rot(q,b),rot(t,b); else rot(t,1-b),rot(t,b); } } } void propagate(np t,E x){ // t->lazy=h(t->lazy,x); // t->key=g(t->key,x,1); // t->sum=g(t->sum,x,t->sz); } void set_propagate(np t,E x){ expose(t); propagate(t,x); push(t); } void push(np t){ // if(t->lazy!=ee){ // if(t->ch[0])propagate(t->ch[0],t->lazy); // if(t->ch[1])propagate(t->ch[1],t->lazy); // t->lazy=ee; // } if(t->rev){ if(t->ch[0])toggle(t->ch[0]); if(t->ch[1])toggle(t->ch[1]); t->rev=0; } } np expose(np t){ np rp=nullptr; for(np cur=t;cur;cur=cur->p){ splay(cur); if(cur->ch[1]){ // toggle(cur->ch[1]); // push(cur->ch[1]); // cerr<<"+"<ch[1]->subtree_sum2<rake_node.all_sum()<ch[1]->id_sum<rake_node_id_sum^=cur->ch[1]->id_sum; cur->rake_node.insert(cur->ch[1]->id_sum,cur->ch[1]->subtree_sum2); // cerr<rake_node.all_sum()<ch[1]=rp; if(cur->ch[1]){ cur->ch[1]->p=cur; // cerr<<"-"<ch[1]->subtree_sum2<rake_node.all_sum()<ch[1]->id_sum<ch[1]); cur->rake_node_id_sum^=cur->ch[1]->id_sum; cur->rake_node.erase(cur->ch[1]->id_sum); // cerr<rake_node.all_sum()<get_path(np x){ vectorvs; auto dfs=[&](auto dfs,np cur){ if(!cur)return; dfs(dfs,cur->ch[1]); vs.push_back(cur->key); dfs(dfs,cur->ch[0]); }; expose(x); dfs(dfs,x); return vs; } void link(np ch,np par){ expose(ch); expose(par); ch->p=par; par->ch[1]=ch; update(par); } void cut(np ch){ expose(ch); np par=ch->ch[0]; ch->ch[0]=nullptr; par->p=nullptr; update(ch); } void toggle(np t){ assert(t); swap(t->ch[0],t->ch[1]); swap(t->subtree_sum,t->subtree_sum_rev); swap(t->subtree_sum2,t->subtree_sum2_rev); t->rev^=1; } void evert(np t){ expose(t); assert(!t->ch[1]); toggle(t); push(t); } np get_root(np x){ expose(x); while(x->ch[0]){ push(x); x=x->ch[0]; } return x; } public: toptree(int sz,Compress comp=Compress(),Rake rake=Rake(),T et=T(),E ee=E()):compress(comp),rake(rake),et(et),ee(ee){ p.resize(sz,nullptr); for(int i=0;ival=val; update(p[t]); } T get_val(int t) { return p[t]->val; } vector get_path(int s,int t){ evert(p[s]); return get_path(p[t]); } void path_add(int s,int t,E x){ evert(p[s]); set_propagate(p[t],x); } T get_path_sum(int s,int t){ evert(p[s]); expose(p[t]); return p[t]->path_sum; } //tを根としたsの部分木の和を得る T get_subtree_sum(int s,int t){ evert(p[t]); expose(p[s]); return p[s]->subtree_sum; } void make_node(T x){ p.emplace_back(new node(p.size(),x)); } void evert(int t){ evert(p[t]); } void link(int s,int t){ evert(p[s]); link(p[s],p[t]); } void cut(int s,int t){ evert(p[s]); cut(p[t]); } bool same(int s,int t){ return get_root(p[s])==get_root(p[t]); } np lca(int s,int t){ if(get_root(p[s])!=get_root(p[t]))return nullptr; expose(p[s]); return expose(p[t]); } }; int main(){ lint n,q; cin>>n>>q; int cnt=0; struct data{ bool zero; lint ans; //パス上のS内の頂点数 lint sz; lint sum,sz2,chsz,chsum; int ch; }; auto compress=[&](const data& s,const data& t){ if(s.zero)return t; if(t.zero)return s; data res; res.ans=s.ans+t.ans+s.sum*t.sz+s.ch*t.sz2+s.ch*(s.chsz*t.sz); res.sz=s.sz+t.sz; res.sum=s.sum; if(t.ch!=-1){ res.ch=t.ch; res.sum+=t.sum; }else{ res.chsum=t.sum; res.chsz=t.sz; res.ch=s.ch; } res.sz2=0; return res; }; auto rake=[&](const data& s,const data& t){ if(s.zero)return t; if(t.zero){ auto res=s; res.ch=-1; return res; } data res; res.ans=s.ans+t.ans; res.sz=s.sz+t.sz; res.sum=s.sum+t.sum; res.sz2=s.sz2+t.sz2+s.sz*t.sz; res.ch=t.ch; // { // cout<<"a"<,decltype(compress),decltype(rake)>lc(n,compress,rake,zero); for(int i=0;i>s>>t; s--;t--; lc.link(s,t); } sets; while(q--){ cnt++; int u,r,v; cin>>u>>r>>v; u--;r--;v--; if(s.count(u)){ lc.set_val(u,data{0,0,0,0,0,0,0,u+1}); s.erase(u); }else{ lc.set_val(u,data{0,0,1,u+1,0,0,0,u+1}); s.emplace(u); } cout<