BZOJ 2157: 旅游 (结构体存变量)
用结构体存变量好像确实能提高运行速度,以后就这么写数据结构了
Code:
#include <cstdio> #include <algorithm> #include <cstring> #define N 200003 #define inf 100000 #define ll long long #define lson t[x].ch[0] #define rson t[x].ch[1] #define setIO(s) freopen(s".in" , "r" , stdin) using namespace std; int sta[N], n; struct Node { int ch[2], f , siz , rev ; ll val , sum , mul , min , max; }t[N << 1]; inline int get(int x) { return t[t[x].f].ch[1] == x; } inline int isrt(int x) { return (!(t[t[x].f].ch[0] == x || t[t[x].f].ch[1] == x)) || (!x); } inline void mark_rev(int x) { swap(lson , rson), t[x].rev ^= 1; } inline void mark_mul(int x, ll y) { t[x].sum *= y, t[x].val *= y, t[x].mul *= y; t[x].min *= y, t[x].max *= y, swap(t[x].min, t[x].max); } inline void pushdown(int x) { if(t[x].rev) { if(lson) mark_rev(lson); if(rson) mark_rev(rson); t[x].rev = 0; } if(t[x].mul != 1) { if(lson) mark_mul(lson , t[x].mul); if(rson) mark_mul(rson , t[x].mul); t[x].mul = 1; } } inline void pushup(int x) { t[x].siz = t[lson].siz + t[rson].siz + 1; t[x].sum = t[lson].sum + t[rson].sum + t[x].val ; t[x].max = max(t[lson].max , t[rson].max) ; t[x].min = min(t[lson].min , t[rson].min) ; if(x > n) { t[x].max = max(t[x].max , t[x].val); t[x].min = min(t[x].min , t[x].val); } } inline void rotate(int x) { int old = t[x].f , fold = t[old].f , which = get(x); if(!isrt(old)) t[fold].ch[t[fold].ch[1] == old] = x; t[old].ch[which] = t[x].ch[which ^ 1], t[t[old].ch[which]].f = old; t[x].ch[which ^ 1] = old, t[old].f = x, t[x].f = fold; pushup(old), pushup(x); } inline void splay(int x) { int v = 0, u = x, i ; for(sta[++ v] = u ; !isrt(u) ; sta[++ v] = t[u].f , u = t[u].f); for(u = t[u].f, i = v ; i ; -- i) pushdown(sta[i]); for(int fa ; (fa = t[x].f) ^ u ; rotate(x)) if(t[fa].f ^ u) rotate(get(fa) == get(x) ? fa : x); } inline void Access(int x) { int y = 0; while(x) { splay(x), rson = y, pushup(x), y = x, x = t[x].f; } } inline void makeroot(int x) { Access(x), splay(x), mark_rev(x); } inline void split(int x, int y) { makeroot(x), Access(y), splay(y); } inline void link(int x, int y) { makeroot(x), t[x].f = y; } int main() { int i, j; scanf("%d", &n); for(i = 0; i < N ; ++i) t[i].mul = 1; for(i = 0; i <= n ; ++i) t[i].min = inf, t[i].max = -inf; for(i = 1; i < n ; ++i) { int u , v , c; scanf("%d%d%d", &u , &v , &c); ++ u , ++ v; t[i + n].val = (ll)c, pushup(i + n), link(u, i + n), link(i + n, v); } int T , x, y; char str[9]; scanf("%d", &T); for(int cas = 1; cas <= T ; ++cas) { scanf("%s%d%d", str, &x, &y); if(str[1] == 'I') split(x + 1, y + 1), printf("%lld\n", t[y + 1].min); if(str[1] == 'A') split(x + 1, y + 1), printf("%lld\n", t[y + 1].max); if(str[0] == 'S') split(x + 1, y + 1), printf("%lld\n", t[y + 1].sum); if(str[0] == 'N') split(x + 1, y + 1), mark_mul(y + 1, -1); if(str[0] == 'C') makeroot(x + n), t[x + n].val = (ll)y, pushup(x + n); } return 0; }