hdu 1698 Just a Hook

这个是我做的线段树第三个题,比前两个区间求和稍微麻烦了一些!

大致意思是:

给一组棍子染色,不同的颜色有不同的值,执行一系列的区间染色后,问这组棍子的总值是多少。

这题我用了两种方法,说是两种,其实就中间的某些细节不太一样!

Nuumber one:

每个线段树的结点,存储该结点所代表区间的染色状况num,如果该区间全为同样的颜色,则用一个正数(1,2,3)表示,如果含有多种颜色,则用-1表示,每次执行染色操作时,如果所要染的颜色与区间颜色一样,则停止,如果所要染区间跟当前结点区间一致,则直接将所要染颜色赋给当前结点的num,否则,如果当前结点区间不是混合色,则先将当前结点的颜色赋给左右子结点的num,并递归下去。

# include<stdio.h>

# define N 400000

struct node{

    int left,right,mid;

    int num;

}a[N];

int val;

void make(int s,int t,int step)

{

    a[step].num=1;

    a[step].left=s;

    a[step].right=t;

    a[step].mid=(s+t)/2;

    if(s==t) return;

    make(s,a[step].mid,2*step);

    make(a[step].mid+1,t,2*step+1);



}

void change(int ans1,int ans2,int step)

{

    if(a[step].num==val) return; 

    if(a[step].left==ans1 && a[step].right==ans2 )  

    {a[step].num=val;return;}

    if(a[step].num!=-1) {a[step*2].num=a[step*2+1].num=a[step].num;}

    a[step].num=-1;

    if(ans1>a[step].mid) change(ans1,ans2,2*step+1);

    else if(ans2<=a[step].mid) change(ans1,ans2,2*step);

    else 

    {

        change(ans1,a[step].mid,2*step);

        change(a[step].mid+1,ans2,2*step+1);

    }

}

int count(int step)

{

    if(a[step].num>0) return (a[step].right-a[step].left+1)*a[step].num;

    return count(step*2)+count(2*step+1);

}

int main()

{

    int ncase=0,n,m,t,ans1,ans2;

    scanf("%d",&t);

    while(t--)

    {

        scanf("%d%d",&n,&m);

        make(1,n,1);

        while(m--)

        {

            scanf("%d%d%d",&ans1,&ans2,&val);

            change(ans1,ans2,1);

        }

        printf("Case %d: The total value of the hook is %d.\n",++ncase,count(1));

    }

    return 0;

}

Number two:
成段更新,总区间求和!
  
    
# include<stdio.h>

# define N 400000

struct node{

    int left,right,mid;

    int num,value;

}a[N];

int val;

void make(int s,int t,int step)

{

    a[step].left=s;

    a[step].right=t;

    a[step].mid=(s+t)/2;

    a[step].num=t-s+1;

    a[step].value=1;

    if(s==t) return;

    make(s,a[step].mid,2*step);

    make(a[step].mid+1,t,2*step+1);

}

void change(int ans1,int ans2,int step)

{

    if(a[step].value==val) return; 

    if(ans1==a[step].left && a[step].right==ans2)  

    {

        a[step].value=val;

        a[step].num=(a[step].right-a[step].left+1)*a[step].value;

        return;

    }

    if(a[step].value>0) 

    {

        a[step*2].value=a[step].value;

        a[step*2].num=(a[step*2].right-a[step*2].left+1)*a[step*2].value;

        

        a[step*2+1].value=a[step].value;

        a[step*2+1].num=(a[step*2+1].right-a[step*2+1].left+1)*a[step*2+1].value;

        a[step].value=0;

    }

    if(ans1>a[step].mid) change(ans1,ans2,2*step+1);

    else if(ans2<=a[step].mid) change(ans1,ans2,2*step);

    else 

    {

        change(ans1,a[step].mid,2*step);

        change(a[step].mid+1,ans2,2*step+1);

    }

    a[step].num=a[2*step].num+a[2*step+1].num;

}

int main()

{

    int ncase=0,n,m,t,ans1,ans2;

    scanf("%d",&t);

    while(t--)

    {

        scanf("%d%d",&n,&m);

        make(1,n,1);

        while(m--)

        {

            scanf("%d%d%d",&ans1,&ans2,&val);

            change(ans1,ans2,1);

        }

        printf("Case %d: The total value of the hook is %d.\n",++ncase,a[1].num);

    }

    return 0;

}







你可能感兴趣的:(HDU)