Submit Info #4117

Problem Lang User Status Time Memory
Dynamic Tree Vertex Add Path Sum cpp hotman AC 594 ms 18.28 MiB

ケース詳細
Name Status Time Memory
example_00 AC 0 ms 0.68 MiB
max_random_00 AC 589 ms 18.25 MiB
max_random_01 AC 594 ms 18.28 MiB
max_random_02 AC 586 ms 18.23 MiB
random_00 AC 365 ms 11.91 MiB
random_01 AC 429 ms 13.91 MiB
random_02 AC 216 ms 5.67 MiB
random_03 AC 242 ms 14.80 MiB
random_04 AC 136 ms 2.30 MiB
small_00 AC 2 ms 0.72 MiB
small_01 AC 3 ms 0.68 MiB
small_02 AC 2 ms 0.72 MiB

#pragma GCC optimize("Ofast") #pragma GCC optimize("unroll-loops") #pragma GCC push_options #pragma GCC target("sse,sse2,sse3,ssse3,sse4,popcnt,abm,mmx,avx,tune=native") #include<bits/stdc++.h> #include <xmmintrin.h> #include <immintrin.h> using namespace::std; __attribute__((constructor))void init(){cin.tie(0);ios::sync_with_stdio(false);cout<<fixed<<setprecision(15);} #include<ext/pb_ds/assoc_container.hpp> #include<ext/pb_ds/tree_policy.hpp> #include <ext/pb_ds/priority_queue.hpp> #include<ext/pb_ds/tag_and_trait.hpp> // #include <boost/multiprecision/cpp_dec_float.hpp> // #include <boost/multiprecision/cpp_int.hpp> // namespace mp = boost::multiprecision; // typedef mp::number<mp::cpp_dec_float<0>> cdouble; // typedef mp::cpp_int cint; template<typename T>using pbds=__gnu_pbds::tree<T,__gnu_pbds::null_type,less<T>,__gnu_pbds::rb_tree_tag,__gnu_pbds::tree_order_statistics_node_update>; template<typename T>using pbds_map=__gnu_pbds::tree<T,T,less<T>,__gnu_pbds::rb_tree_tag,__gnu_pbds::tree_order_statistics_node_update>; template<typename T,typename E>using hash_map=__gnu_pbds::gp_hash_table<T,E>; template<typename T>using pqueue =__gnu_pbds::priority_queue<T, greater<T>,__gnu_pbds::rc_binomial_heap_tag>; typedef long long lint; #define INF (1LL<<60) #define IINF (1<<30) #define EPS (1e-10) //#define MOD 1000000007LL #define MOD 998244353LL typedef vector<lint> vec; typedef vector<vector<lint>> mat; typedef vector<vector<vector<lint>>> mat3; typedef vector<string> svec; typedef vector<vector<string>> smat; template<typename T>inline void numout(T t){bool f=0;for(auto i:t){cout<<(f?" ":"")<<i<INF/2?i:"INF";f=1;}cout<<endl;} template<typename T>inline void numout2(T t){for(auto i:t)numout(i);} template<typename T>inline void output(T t){bool f=0;for(auto i:t){cout<<(f?" ":"")<<i;f=1;}cout<<endl;} template<typename T>inline void output2(T t){for(auto i:t)output(i);} template<typename T>inline void _output(T t){bool f=0;for(lint i=0;i<t.size();i++){cout<<f?"":" "<<t[i];f=1;}cout<<endl;} template<typename T>inline void _output2(T t){for(lint i=0;i<t.size();i++)output(t[i]);} #define rep(i,n) for(lint i=0;i<lint(n);++i) #define repi(i,a,b) for(lint i=lint(a);i<(lint)(b);++i) #define rrep(i,n) for(lint i=lint(n)-1;i>=0;--i) #define rrepi(i,a,b) for(lint i=lint(b)-1;i>=lint(a);--i) #define irep(i) for(lint i=0;;++i) #define all(n) begin(n),end(n) #define dist(a,b,c,d) sqrt(pow(a-c,2)+pow(b-d,2)) inline lint gcd(lint A,lint B){return B?gcd(B,A%B):A;} inline lint lcm(lint A,lint B){return A/gcd(A,B)*B;} // inline cint cgcd(cint A,cint B){return B?cgcd(B,A%B):A;} // inline cint clcm(cint A,cint B){return A/cgcd(A,B)*B;} inline bool chmin(auto& s,const auto& t){bool res=s>t;s=min(s,t);return res;} inline bool chmax(auto& s,const auto& t){bool res=s<t;s=max(s,t);return res;} const vector<lint> dx={1,0,-1,0,1,1,-1,-1}; const vector<lint> dy={0,1,0,-1,1,-1,1,-1}; #define SUM(v) accumulate(all(v),0LL) auto call=[&](auto f,auto... args){return f(f,args...);}; template<typename T,typename E> class link_cut{ public: struct node; using np=node*; struct node{ np ch[2]={nullptr,nullptr}; np p=nullptr; int idx; T key,sum; bool rev=0; E lazy=ee; int sz; node(){} node(int idx,T key):idx(idx),key(key),sum(key),sz(1){} bool is_root() { return !p||(p->ch[0]!=this&&p->ch[1]!=this); } }; int size(np t){return t?t->sz:0;} void update(np t){ t->sz=size(t->ch[0])+1+size(t->ch[1]); if(t->ch[0])t->sum=f(t->ch[0]->sum,t->key); else t->sum=t->key; if(t->ch[1])t->sum=f(t->sum,t->ch[1]->sum); } 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 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); cur->ch[1]=rp; update(cur); rp=cur; } splay(t); return rp; } vector<int>get_path(np x){ vector<int>vs; function<void(np)>dfs=[&](np cur){ if(!cur)return; push(cur); dfs(cur->ch[1]); vs.push_back(cur->idx); dfs(cur->ch[0]); }; expose(x); 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]); t->sum=s(t->sum); t->rev^=1; } void evert(np t){ expose(t); toggle(t); push(t); } np get_root(np x){ expose(x); while(x->l){ push(x); x=x->l; } return x; } vector<np>p; static constexpr T et=0; static constexpr E ee=0; T s(T s){ return s; } T f(T s,T t){ return s+t; } T g(T s,E t,int len){ return s+t*len; } E h(E s,E t){ return s+t; } public: link_cut(int sz){ p.resize(sz,nullptr); for(int i=0;i<sz;i++)p[i]=new node(i,et); } link_cut(){} vector<int> 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]->sum; } void make_node(T x){ p.emplace_back(new node(p.size(),x)); } 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]); } 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(){ link_cut<lint,lint>lc; lint n,q; cin>>n>>q; rep(i,n){ lint x; cin>>x; lc.make_node(x); } rep(i,n-1){ lint s,t; cin>>s>>t; lc.link(s,t); } rep(i,q){ lint x; cin>>x; if(x==0){ lint s,t,u,r; cin>>s>>t>>u>>r; lc.cut(s,t); lc.link(u,r); } if(x==1){ lint s,t; cin>>s>>t; lc.path_add(s,s,t); } if(x==2){ lint s,t; cin>>s>>t; cout<<lc.get_path_sum(s,t)<<endl; } } }