hdu 3074 Multiply game

线段树简单题:区间乘积,单点修改

这题其实难度和之前的一样本来不想做的,但是学习了高手的代码,所以自己想实现一遍

果然用了新的代码风格,时间大大提高,空间都减少,不过代码量好像没怎么变,一口气冲进了第10名

10 G-rated 281MS 1280K 1572B C++ 2013-01-31 12:57:58
#include <cstdio>

#define N 50010

const int MOD=1000000007;

__int64 mul[4*N];

int n,m;



void updata(int a ,int b ,int p ,int e ,int root)

{

    if(a==b)

    {

        mul[root]=e;

        return ;

    }

    int mid=(a+b)>>1;

    if(p<=mid)

        updata(a,mid,p,e,root<<1);

    else

        updata(mid+1,b,p,e,root<<1|1);

    mul[root]=(mul[root<<1]*mul[root<<1|1])%MOD;

    return ;

}



__int64 query(int a ,int b ,int l ,int r ,int root)

{

    int mid=(a+b)>>1;

    if(a==l && b==r)

        return mul[root];

    if(r<=mid)

        return query(a,mid,l,r,root<<1);

    else if(l>mid)

        return query(mid+1,b,l,r,root<<1|1);

    else

        return (query(a,mid,l,mid,root<<1)*query(mid+1,b,mid+1,r,root<<1|1))%MOD;

}



void build(int a ,int b , int root)

{

    if(a==b)

    {

        scanf("%I64d",&mul[root]);

        //printf("[%d , %d] , %d\n",a,b,mul[root]);

        return ;

    }



    int mid=(a+b)>>1;

    build(a,mid,root<<1);

    build(mid+1,b,root<<1 | 1);

    mul[root]=(mul[root<<1]*mul[root<<1 | 1])%MOD;

    //printf("[%d , %d] , %d\n",a,b,mul[root]);

    return ;

}



int main()

{

    int T;

    scanf("%d",&T);

    while(T--)

    {

        scanf("%d",&n);

        build(1,n,1);

        scanf("%d",&m);

        while(m--)

        {

            int k,a,b;

            scanf("%d%d%d",&k,&a,&b);

            if(!k)  //查询区间乘积

                printf("%I64d\n",query(1,n,a,b,1));

            else    //更改单点数值

                updata(1,n,a,b,1);

        }

    }

    return 0;

}

 

 

关于query函数的另一个写法

实际上我更喜欢上面的写法,因为更容易理解,符合人的思维。而且从时间上看,上面的写法比接下来的这个写法要更快。

不过这个写法代码量就少一些

这个写法是基于线段树的性质:线段树中任意两个节点的关系要么是包含关系,要么是相离关系,不可能出现相交

 

__int64 query(int a ,int b ,int l ,int r ,int root)

{

    if(r<a || l>b)  return 1; //完全无交集

    if(l<=a && b<=r) return mul[root];

    int mid=(a+b)>>1;

    return (query(a,mid,l,r,root<<1)*query(mid+1,b,l,r,root<<1|1))%MOD;

}

 

你可能感兴趣的:(game)