[国家集训队2012]tree(伍一鸣)
2015-09-07 19:57
302 查看
题目链接,直接 LCT 就好,注意取模,还有数据很强,51061251061^2 会爆 intint
#include <cstdio> #include <cstdlib> #include <cstring> #include <cmath> #include <ctime> #include <vector> #include <utility> #include <stack> #include <queue> #include <iostream> #include <algorithm> template<class Num>void read(Num &x) { char c; int flag = 1; while((c = getchar()) < '0' || c > '9') if(c == '-') flag *= -1; x = c - '0'; while((c = getchar()) >= '0' && c <= '9') x = (x<<3) + (x<<1) + (c-'0'); x *= flag; return; } template<class Num>void write(Num x) { if(!x) {putchar('0');return;} if(x < 0) putchar('-'), x = -x; static char s[20];int sl = 0; while(x) s[sl++] = x%10 + '0',x /= 10; while(sl) putchar(s[--sl]); } const int maxn = 1e5 + 50, maxq = maxn; const int INF = 0x3f3f3f3f, Nya = -1; const int Mod = 51061; int n, m, q; unsigned int val[maxn], sum[maxn]; int size[maxn]; unsigned int mul[maxn], add[maxn]; namespace LCT { int c[maxn][2], fa[maxn]; int rev[maxn]; void update(int x) { sum[x] = (sum[c[x][0]] + sum[c[x][1]] + val[x]) % Mod; size[x] = size[c[x][0]] + size[c[x][1]] + 1; } void _mul(int v,int x) { val[v] = (val[v] * x) % Mod; sum[v] = (sum[v] * x) % Mod; mul[v] = (mul[v] * x) % Mod; add[v] = (add[v] * x) % Mod; } void _add(int v,int x) { val[v] = (val[v] + x) % Mod; sum[v] = (sum[v] + x * size[v]) % Mod; add[v] = (add[v] + x) % Mod; } void pushdown(int x) { int v; if(rev[x]) { rev[c[x][0]] ^= 1; rev[c[x][1]] ^= 1; std::swap(c[x][0], c[x][1]); rev[x] = 0; } if(mul[x] != 1) { if(c[x][0]) _mul(c[x][0], mul[x]); if(c[x][1]) _mul(c[x][1], mul[x]); mul[x] = 1; } if(add[x]) { if(c[x][0]) _add(c[x][0], add[x]); if(c[x][1]) _add(c[x][1], add[x]); add[x] = 0; } } bool isroot(int x) { return x != c[fa[x]][0] && x != c[fa[x]][1]; } void rotate(int x) { int y = fa[x], z = fa[y], i, j; pushdown(y), pushdown(x); j = (c[z][1] == y), i = (c[y][1] == x); if(!isroot(y)) c[z][j] = x; else fa[x] = fa[y], fa[y] = 0; if(c[x][i^1]) fa[c[x][i^1]] = y; fa[x] = z, fa[y] = x; c[y][i] = c[x][i^1], c[x][i^1] = y; update(y), update(x); } void Splay(int v) { int g = fa[v], h = fa[g]; pushdown(v); while(!isroot(v)) { if(!isroot(g)) { if((c[h][1] == g)^(c[g][1] == v)) rotate(v); else rotate(g); } rotate(v), g = fa[v], h = fa[g]; } update(v); } void access(int v) { int u = v, e = v; v = 0; while(u) { Splay(u); int &t = c[u][1]; t = v, update(u); v = u, u = fa[u]; } Splay(e); } void makeroot(int v) { access(v); rev[v] ^= 1; } void join(int v,int u) { makeroot(v); fa[v] = u; access(v); } void cut(int v,int u) { makeroot(v); access(u); c[u][0] = fa[v] = 0; } } void init() { int u, v; read(n), read(q); for(int i = 1; i <= n; i++) sum[i] = val[i] = mul[i] = size[i] = 1; for(int i = 1; i < n; i++) read(u), read(v), LCT::join(u, v); } void solve() { char str[5]; int u, v, x, y; while(q--) { scanf("%s", str); if(str[0] == '+') { read(u), read(v), read(x); LCT::makeroot(u), LCT::access(v), LCT::_add(v, x); } else if(str[0] == '-') { read(u), read(v), read(x), read(y); LCT::cut(u, v), LCT::join(x, y); } else if(str[0] == '*') { read(u), read(v), read(x); LCT::makeroot(u), LCT::access(v), LCT::_mul(v, x); } else if(str[0] == '/') { read(u), read(v); LCT::makeroot(u), LCT::access(v); write(sum[v]), puts(""); } else std::cerr << "error!"; } } int main() { freopen("nt2012_wym_tree.in","r",stdin); freopen("nt2012_wym_tree.out","w",stdout); init(); solve(); fclose(stdin); fclose(stdout); return 0; }
相关文章推荐
- Win10系统给绿色版msysGit添加Git Bash Here
- 2015.9.7 来到B公司的第三天
- 等效全向辐射功率(EIRP)
- skia DrawLooper
- Processing 练习(6)- 模拟电磁场 - 三角函数应用
- TCP标志位之RST
- FTP主动模式和被动模式的区别
- C++默认参数注意事项
- 最大公约数gcd实现
- 继承 初始化方法 遍历构造器
- oracle 各种常用函数讲解
- 沟通的囧途
- 网络编程
- Spinner下拉列表组件的3种数据绑定方式
- mysql中文进行全文索引支持问题
- ioS开发之网络--网络基础概况
- 深入理解java异常处理机制
- poj 2251 简单搜索bfs
- AJAX基础
- Mini调试器捉虫记