bzoj 2631: tree link-cut-tree
2017-03-13 21:41
316 查看
题目:
Description
一棵n个点的树,每个点的初始权值为1。对于这棵树有q个操作,每个操作为以下四种操作之一:
+ u v c:将u到v的路径上的点的权值都加上自然数c;
- u1 v1 u2 v2:将树中原有的边(u1,v1)删除,加入一条新边(u2,v2),保证操作完之后仍然是一棵树;
* u v c:将u到v的路径上的点的权值都乘上自然数c;
/ u v:询问u到v的路径上的点的权值和,求出答案对于51061的余数。Input
第一行两个整数n,q
接下来n-1行每行两个正整数u,v,描述这棵树
接下来q行,每行描述一个操作
Output
对于每个/对应的答案输出一行
题解
模板题
用了15mins打完,调了半小时
#include <cstdio> #include <cstring> #include <algorithm> using namespace std; typedef long long ll; inline void read(ll &x){ x=0;char ch;bool flag = false; while(ch=getchar(),ch<'!');if(ch == '-') ch=getchar(),flag = true; while(x=10*x+ch-'0',ch=getchar(),ch>'!');if(flag) x=-x; } const ll mod = 51061; const ll maxn = 210010; struct Node{ Node *ch[2],*fa; ll mul,add,w,sum,tag; ll siz; void update(); void pushdown(); void set(); }*null; Node mem[maxn],*it; inline void init(){ it = mem;null = it++; null->ch[0] = null->ch[1] = null->fa = null; null->mul = null->add = null->w = null->sum = 0; null->tag = null->siz = 0; } inline Node* newNode(ll w){ Node *p = it++;p->ch[0] = p->ch[1] = p->fa = null; p->mul = 1;p->siz = 1; p->add = p->tag = 0;p->w = p->sum = w;return p; } inline void Node::update(){ if(this == null) return; sum = (ch[0]->sum + ch[1]->sum + w) % mod; siz = (ch[0]->siz + ch[1]->siz + 1); } inline void Node::pushdown(){ if(this == null) return; if(mul != 1){ if(ch[0] != null){ ch[0]->add = ch[0]->add*mul % mod; ch[0]->mul = ch[0]->mul*mul % mod; ch[0]->w = ch[0]->w*mul % mod; ch[0]->sum = ch[0]->sum*mul % mod; } if(ch[1] != null){ ch[1]->add = ch[1]->add*mul % mod; ch[1]->mul = ch[1]->mul*mul % mod; ch[1]->w = ch[1]->w*mul % mod; ch[1]->sum = ch[1]->sum*mul % mod; } mul = 1; } if(add != 0){ if(ch[0] != null){ ch[0]->add = (ch[0]->add + add) % mod; ch[0]->sum = (ch[0]->sum + add*ch[0]->siz) % mod; ch[0]->w = (ch[0]->w + add) % mod; } if(ch[1] != null){ ch[1]->add = (ch[1]->add + add) % mod; ch[1]->sum = (ch[1]->sum + add*ch[1]->siz) % mod; ch[1]->w = (ch[1]->w + add) % mod; } add = 0; } if(tag != 0){ if(ch[0] != null) ch[0]->tag ^= 1; if(ch[1] != null) ch[1]->tag ^= 1; swap(ch[0],ch[1]);tag = 0; } } inline void rotate(Node *p,Node *x){ ll k = p == x->ch[1]; Node *y = p->ch[k^1],*z = x->fa; if(z->ch[0] == x) z->ch[0] = p; if(z->ch[1] == x) z->ch[1] = p; if(y != null) y->fa = x; p->fa = z;p->ch[k^1] = x; x->fa = p;x->ch[k] = y; x->update();p->update(); } inline bool isroot(Node *p){ return (p == null) || (p->fa->ch[0] != p && p->fa->ch[1] != p); } inline void Splay(Node *p){ p->pushdown(); while(!isroot(p)){ Node *x = p->fa,*y = x->fa; y->pushdown();x->pushdown();p->pushdown(); if(isroot(x)) rotate(p,x); else if((p == x->ch[0])^(x == y->ch[0])) rotate(p,x),rotate(p,y); else rotate(x,y),rotate(p,x); }p->update(); } inline Node* Access(Node *x){ for(Node *y = null;x != null;y = x,x = x->fa) Splay(x),x->ch[1] = y,x->update(); return x; } inline void makeRoot(Node *x){ Access(x);Splay(x);x->tag ^= 1; } inline void link(Node *x,Node *y){ makeRoot(x);x->fa = y; } inline void cut(Node *x,Node *y){ makeRoot(x);Access(y);Splay(y); y->ch[0] = y->ch[0]->fa = null; y->update(); } inline void inc(Node *x,Node *y,ll w){ makeRoot(x);Access(y);Splay(y); y->add += w;y->add %= mod; y->sum += w*y->siz; y->sum %= mod; y->w += w;y->w %= mod; } inline void mul(Node *x,Node *y,ll w){ makeRoot(x);Access(y);Splay(y); y->add *= w;y->add %= mod; y->mul *= w;y->mul %= mod; y->sum *= w;y->sum %= mod; y->w *= w;y->w %= mod; } inline ll query(Node *x,Node *y){ makeRoot(x);Access(y);Splay(y); return y->sum; } int main(){ init(); ll n,q;read(n);read(q); for(ll i=1;i<=n;++i) newNode(1); for(ll i=1,u,v;i<n;++i){ read(u);read(v); link(mem+u,mem+v); } char ch; ll u,v,x; while(q--){ while(ch = getchar(),ch<'!'); if(ch == '+'){ read(u);read(v);read(x); inc(mem+u,mem+v,x); }else if(ch == '-'){ read(u);read(v); cut(mem+u,mem+v); read(u);read(v); link(mem+u,mem+v); }else if(ch == '*'){ read(u);read(v);read(x); mul(mem+u,mem+v,x); }else if(ch == '/'){ read(u);read(v); printf("%lld\n",query(mem+u,mem+v)); } } getchar();getchar(); return 0; }
相关文章推荐
- BZOJ 2631 tree 动态树(Link-Cut-Tree)
- Link-Cut-Tree:【BZOJ2631】Tree
- BZOJ2631: tree link-cut-tree
- BZOJ2631: tree Link-cut-tree
- BZOJ 2631: tree Link_Cut_Tree
- BZOJ-2631 tree Link-Cut-Tree
- BZOJ 2243(Link Cut Tree解法)
- bzoj 2049: [Sdoi2008]Cave 洞穴勘测 (link-cut-tree)
- bzoj 2002 link cut tree(LCT)
- BZOJ 1453 Wc2005 Dface双面棋盘 Link-Cut-Tree
- BZOJ 3306 树 Link-Cut-Tree+set
- BZOJ 2049 洞穴勘测 Link-Cut-Tree(LCT)
- [bzoj2049][Sdoi2008]Cave 洞穴勘测 Link-Cut-Tree
- bzoj3282 Tree&luogu3690 【模板】Link Cut Tree (动态树)
- BZOJ 2002 弹飞绵羊 Link-Cut-Tree(LCT)
- bzoj 2594: 水管局长数据加强版 Link-Cut-Tree
- bzoj 3669: [Noi2014]魔法森林 link cut tree
- BZOJ4025(LCT+LCT+LinkCutTree)
- BZOJ 2759 一个动态树好题 Link-Cut-Tree+扩展欧几里得
- BZOJ 2049: [Sdoi2008]Cave 洞穴勘测 link cut tree