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

这题和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
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值