【线段树】 HDOJ 4942 Game on S♂play

来源:互联网 发布:淘宝5年老店标志没了 编辑:程序博客网 时间:2024/04/27 17:48

这题和splay,和treap一毛钱关系都没有,用线段树维护一下就好了。。。。比赛的时候我竟然傻到用treap维护。。。

#include <iostream>  #include <queue>  #include <stack>  #include <map>  #include <set>  #include <bitset>  #include <cstdio>  #include <algorithm>  #include <cstring>  #include <climits>  #include <cstdlib>#include <cmath>#include <time.h>#define maxn 100005#define maxm 100005#define eps 1e-10#define mod 1000000007#define INF 1e9#define lowbit(x) (x&(-x))  #define ls o<<1#define rs o<<1 | 1#define lson o<<1, L, mid  #define rson o<<1 | 1, mid+1, R  typedef long long LL;//typedef int LL;using namespace std;struct node{int s, id;LL w, v;node *ch[2], *fa;void maintain(void){s = ch[0]->s + ch[1]->s + 1;w = (ch[0]->w + ch[1]->w + v) % mod;}}*null, *root[maxn], C[maxn], *top, *rt;int f[maxn], in[maxn], num[maxn];LL sum[maxn<<2];queue<int> q;int idx, ql, qr, n, m, p;LL v;void rotate(node* o, int d){node *k = o->ch[d^1];if(k == null) return;if(o->fa != null) {if(o->fa->ch[0] == o) o->fa->ch[0] = k;else o->fa->ch[1] = k;}o->ch[d^1] = k->ch[d];if(o->ch[d^1] != null) o->ch[d^1]->fa = o;k->fa = o->fa, o->fa = k, k->ch[d] = o;o->maintain(), k->maintain();}void init(void){idx = 0;top = C;null = top++;memset(in, 0, sizeof in);memset(f, 0, sizeof f);null->v = null->w = null->s = 0;null->ch[0] = null->ch[1] = null->fa = null;scanf("%d%d", &n, &m);for(int i = 0; i <= n; i++) root[i] = top++, root[i]->fa = null;}void read(void){int w, x, y;for(int i = 1; i <= n; i++) {scanf("%d%d%d", &w, &x, &y);root[i]->v = w;if(x == 0) root[i]->ch[0] = null;else root[i]->ch[0] = root[x], root[x]->fa = root[i], f[x] = i, in[i]++;if(y == 0) root[i]->ch[1] = null;else root[i]->ch[1] = root[y], root[y]->fa = root[i], f[y] = i, in[i]++;}}void build(void){for(int i = 1; i <= n; i++) if(!in[i]) q.push(i);while(!q.empty()) {int x = q.front();q.pop();root[x]->maintain();rt = root[x];in[f[x]]--;if(!in[f[x]] && f[x]) q.push(f[x]);}}void solve(node* &o){if(o->ch[0] != null) solve(o->ch[0]);o->id = ++idx;if(o->ch[1] != null) solve(o->ch[1]);}void _build(int o, int L, int R){if(L == R) {sum[o] = num[L] % mod;return;}int mid = (L+R)>>1;_build(lson);_build(rson);sum[o] = sum[ls] * sum[rs] % mod;}void updata(int o, int L, int R){if(L == R) {sum[o] = v;return;}int mid = (L+R)>>1;if(p <= mid) updata(lson);else updata(rson);sum[o] = sum[ls] * sum[rs] % mod;}LL query(int o, int L, int R){if(ql <= L && qr >= R) return sum[o];int mid;LL ans = 1;mid = (L+R)>>1;if(ql <= mid) ans = (ans * query(lson)) % mod;if(qr > mid) ans = (ans * query(rson)) % mod;return ans;}void work(void){int k, u, p1, p2;LL v1, v2;for(int i = 1; i <= n; i++) num[root[i]->id] = root[i]->w;_build(1, 1, n);while(m--) {scanf("%d%d", &k, &u);if(k == 2) {ql = root[u]->id - root[u]->ch[0]->s;qr = root[u]->id + root[u]->ch[1]->s;printf("%I64d\n", query(1, 1, n));}else {if(root[u]->ch[k] == null) continue;p1 = root[u]->id;p2 = root[u]->ch[k]->id;rotate(root[u], k^1);v1 = root[u]->w;v2 = root[u]->fa->w;p = p1, v = v1;updata(1, 1, n);p = p2, v = v2;updata(1, 1, n);}}}int main(void){int _, __;while(scanf("%d", &_)!=EOF) {__ = 0;while(_--) {init();read();build();solve(rt);printf("Case #%d:\n", ++__);work();}}return 0;}


0 0
原创粉丝点击