杭电1698 just a hook (线段树)(区间更改值)

来源:互联网 发布:域名购买哪个网站好 编辑:程序博客网 时间:2024/06/03 13:43

Just a Hook

Time Limit: 4000/2000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)
Total Submission(s): 24416    Accepted Submission(s): 12165


Problem Description
In the game of DotA, Pudge’s meat hook is actually the most horrible thing for most of the heroes. The hook is made up of several consecutive metallic sticks which are of the same length.



Now Pudge wants to do some operations on the hook.

Let us number the consecutive metallic sticks of the hook from 1 to N. For each operation, Pudge can change the consecutive metallic sticks, numbered from X to Y, into cupreous sticks, silver sticks or golden sticks.
The total value of the hook is calculated as the sum of values of N metallic sticks. More precisely, the value for each kind of stick is calculated as follows:

For each cupreous stick, the value is 1.
For each silver stick, the value is 2.
For each golden stick, the value is 3.

Pudge wants to know the total value of the hook after performing the operations.
You may consider the original hook is made up of cupreous sticks.
 

Input
The input consists of several test cases. The first line of the input is the number of the cases. There are no more than 10 cases.
For each case, the first line contains an integer N, 1<=N<=100,000, which is the number of the sticks of Pudge’s meat hook and the second line contains an integer Q, 0<=Q<=100,000, which is the number of the operations.
Next Q lines, each line contains three integers X, Y, 1<=X<=Y<=N, Z, 1<=Z<=3, which defines an operation: change the sticks numbered from X to Y into the metal kind Z, where Z=1 represents the cupreous kind, Z=2 represents the silver kind and Z=3 represents the golden kind.
 

Output
For each case, print a number in a line representing the total value of the hook after the operations. Use the format in the example.
 

Sample Input
11021 5 25 9 3
 

Sample Output
Case 1: The total value of the hook is 24.

思路还是比较简单的一道线段树的区间值改变的问题

作为一个新手的我来说 其实这个题还是卡了我很长很长时间的~

至于到底多长时间呢~

呵呵哒~

呵呵哒~

呵呵哒~

呵呵哒~

呵呵哒~

呵呵哒~

呵呵哒~

HEHEDA ~~`

呵呵哒~

直到刚刚重新干掉了bug,可算是在杭电上边见了红~

这来之不易的红色AC

也不能算是第一次卡这么久的题吧 .不过真的比较激动~

不扯犊子了

接下来说说这个题

首先介绍一下线段树的图:

运用懒惰标记的方法进行区间更新值.

至于什么事懒惰标记 ~我的理解就是一种标记维护树内数据的方式去从某一个子节点覆盖值.

蓝后继续向下子节点覆盖值~

一道看似很简单的区间覆盖问题 的学习对一个新手来说是真的很痛苦的~

这里贴上代码和自己的理解

#include<stdio.h>
#include<string.h>
using namespace std;
#define lson l,m,rt*2
#define rson m+1,r,rt*2+1
int tree[100001*4];//树
int flag[100001*4];//懒惰标记数组
void pushup(int rt)
{
    tree[rt]=tree[rt<<1]+tree[rt<<1|1];//向上维护树内数据
}
void pushdown(int l,int r,int rt)
{
    if(flag[rt])//被懒惰标记上的节点要给他们的子节点覆盖上值 同时也要给他们的子节点懒惰标记上~
    {
        int m=(l+r)/2;
        flag[rt*2]=flag[rt*2+1]=flag[rt];
        tree[rt*2]=(m-l+1)*flag[rt];//这里是覆盖一段值(区间覆盖值)所以要考虑区间长度的问题 这里希望读者细细品味.
        tree[rt*2+1]=(r-(m+1)+1)*flag[rt];
        flag[rt]=0;
    }
}
void build( int l ,int r , int rt )//简简单单的建树函数
{
    if( l == r )//如果递归找到了叶子
    {
        tree[rt]=1;//就初始化价值1
        flag[rt]=0;//同时初始化清除懒惰标记
    }
    else
    {
        int m = (l+r)>>1 ;//m是罚分点
        build(lson) ;//建左子树
        build(rson) ;//右边
        pushup(rt) ;//向上求区间和(维护树内数据)
    }
}
void update(int L,int R,int c,int l,int r,int rt)//目的左区间 目的右区间 目的修改值.
{
        if(L<=l&&r<=R)//这里覆盖的是区间(减枝作用(自行体会作用~))
        {
        tree[rt]=c*((r-l)+1);//当前节点覆盖值
        flag[rt]=c;//懒惰标记当前节点(pushdown的操作覆盖了区间子区间的值)
        return ;//不能少了这个步骤 会re
        }
        pushdown(l,r,rt);
        int m=(l+r)/2;
        if(L<=m)//目的修改区间的左极限位子在当前节点左子树中  
        {
            update(L,R,c,lson);//就要在左子树修改数据~
        }
        if(m<R)//目的修改区间
        {
            update(L,R,c,rson);//就要在右子树修改数据~
        }
        pushup(rt);
}
int main()
{
    int t;
    int kase=0;
    scanf("%d",&t);
    while(t--)
    {
        int n,m;
        scanf("%d%d",&n,&m);
        memset(tree,0,sizeof(tree));
        memset(flag,0,sizeof(flag));
        build(1,n,1);
        while(m--)
        {
            int x,y,c;
            scanf("%d%d%d",&x,&y,&c);
            update(x,y,c,1,n,1);
        }
       printf("Case %d: The total value of the hook is %d.\n",++kase,tree[1]);
    }
}

0 0
原创粉丝点击