[线段树]HDU 4942——Game on S♂play

来源:互联网 发布:网络赢钱游戏 编辑:程序博客网 时间:2024/03/28 21:51

题目梗概

给出一棵树,定义一个节点的有趣值为该节点为根的树的权值和。

现在可以旋转一个节点,询问任意子树的有趣值之积。

解题思路

不管树怎么旋转,这棵树的中序遍历是不变的。

维护每个节点控制范围和有趣值。

用线段树维护有趣值的积。

#pragma comment (linker,"/STACK:102400000,102400000")#include<cstdio>#include<cstring>#define LL long long#define maxn 100005#define tt 1000000007#define ls x<<1#define rs (x<<1)+1using namespace std;struct jz{    int son[2],L,R,fa;    LL w;}a[maxn],t[maxn*4];int T,n,m,w[maxn],tot,id[maxn],h[maxn];inline int _read(){    int num=0;char ch=getchar();    while (ch<'0'||ch>'9') ch=getchar();    while (ch>='0'&&ch<='9') num=num*10+ch-48,ch=getchar();    return num;}inline int min(int x,int y){if (x<y) return x;return y;}inline int max(int x,int y){if (x>y) return x;return y;}void updata(int x){t[x].w=(t[ls].w*t[rs].w)%tt;}void renew(int x){    a[x].L=a[x].R=id[x];a[x].w=w[x];    for (int i=0;i<2;i++) if (a[x].son[i]){        a[x].L=min(a[x].L,a[a[x].son[i]].L);a[x].R=max(a[x].R,a[a[x].son[i]].R);        a[x].w+=a[a[x].son[i]].w;    }}void DFS(int x){    if (!x) return;    DFS(a[x].son[0]);    id[x]=++tot;h[tot]=x;    DFS(a[x].son[1]);    renew(x);}void Build(int x,int L,int R){    t[x].L=L,t[x].R=R;    if (L==R){t[x].w=a[h[L]].w;return;}    int mid=L+(R-L>>1);    Build(ls,L,mid);Build(rs,mid+1,R);    updata(x);}void change(int x,int p,LL y){    if (t[x].L==t[x].R){t[x].w=y;return;}    int mid=t[x].L+(t[x].R-t[x].L>>1);    if (p<=mid) change(ls,p,y);else change(rs,p,y);    updata(x);}LL query(int x,int L,int R){    if (L==t[x].L&&R==t[x].R) return t[x].w;    int mid=t[x].L+(t[x].R-t[x].L>>1);    if (R<=mid) return query(ls,L,R);else    if (L>mid) return query(rs,L,R);else    return (query(ls,L,mid)*query(rs,mid+1,R))%tt;}void turn(int x,int d){    int t=a[x].son[d],ff=a[x].fa;    a[x].son[d]=a[t].son[d^1];a[a[t].son[d^1]].fa=x;a[t].son[d^1]=x;    if (ff) a[ff].son[x!=a[ff].son[0]]=t;    a[t].fa=ff;a[x].fa=t;    renew(x);renew(t);    change(1,id[x],a[x].w);change(1,id[t],a[t].w);}int main(){    freopen("exam.in","r",stdin);    freopen("exam.out","w",stdout);    T=_read();    for (int t=1;t<=T;t++){        n=_read(),m=_read();        memset(a,0,sizeof(a));        for (int i=1;i<=n;i++){            w[i]=_read(),a[i].son[0]=_read(),a[i].son[1]=_read();            if (a[i].son[0]) a[a[i].son[0]].fa=i;            if (a[i].son[1]) a[a[i].son[1]].fa=i;        }        tot=0;DFS(1);Build(1,1,n);        printf("Case #%d:\n",t);        for (int i=1;i<=m;i++){            int y=_read(),x=_read();            if (y==2) printf("%lld\n",query(1,a[x].L,a[x].R)%tt);            if (y==0&&a[x].son[0]) turn(x,0);            if (y==1&&a[x].son[1]) turn(x,1);        }    }}
原创粉丝点击