Just a Hook(线段树) HDU - 1698

题意:给你一个长度为N节的金属钩子,钩子分为铜,银,金三种。

铜为1,银为2,金为3;

一开始都是铜钩子,经过q次变化后,问N节钩子的数目之和。


#define _CRT_SECURE_NO_WARNINGS
#include<iostream>
#include<cstring>
#include<stdio.h>
#include<algorithm>
#include<map>
#include<queue>
#include<set>
#include <sstream>
#include<vector>
#include<cmath>    
#include<stack>
#include<time.h>
#include<ctime>
using namespace std;
#define inf 1<<30
#define eps 1e-7
#define LD long double
#define LL long long
#define maxn 1000005
struct node
{
    int L, R, sum = 0, flag;
}tree[maxn];
void up(int step)
{
    tree[step].sum = tree[step * 2].sum + tree[step * 2 + 1].sum;
}
void build(int step, int L, int R)//建树
{
    tree[step].L = L;
    tree[step].R = R;
    tree[step].flag = 1;//标记,因为一开始L-R都是铜钩子,即1;
    if (tree[step].L == tree[step].R)
    {
        tree[step].sum = 1;
        return;
    }
    int mid = (L + R) >> 1;
    build(step << 1, L, mid);
    build(step << 1 | 1, mid + 1, R);
    up(step);
}
void change(int step, int x, int y, int val)
{
    if (tree[step].flag == val)//当前step的L-R范围都是val金属
    {
        return;
    }
    if (tree[step].L == x && tree[step].R == y)//L-R刚好和x-y完全重合,直接改变标记即可
    {
        tree[step].flag = val;
        return;
    }
    if (tree[step].flag)//当前存在标记,但又不和val相同,L-R也不与x-y完全重合
    {
        tree[step * 2].flag = tree[step].flag;
        tree[step * 2 + 1].flag = tree[step].flag;
        tree[step].flag = 0;//把当前标记为0,因为已经把标记传递到左右子树了
    }
    int mid = (tree[step].L + tree[step].R) >> 1;
    if (y <= mid)//在左边
        change(step * 2, x, y, val);
    else if (x > mid)//右边
        change(step * 2 + 1, x, y, val);
    else//两边都有
    {
        change(step * 2, x, mid, val);
        change(step * 2 + 1, mid + 1, y, val);
    }
    tree[step].sum = tree[step * 2].sum + tree[step * 2 + 1].sum;
}
int query(int step)//计算数目之和
{
    if (tree[step].flag)//标记不为0,说明step的L-R都是flag金属
        return (tree[step].R - tree[step].L + 1) * tree[step].flag;
    else 
        return query(step * 2) + query(step * 2 + 1);
}
int main()
{
    int T, Case = 1;
    scanf("%d", &T);
    while (T--)
    {
        int N;
        scanf("%d", &N);
        build(1, 1, N);
        int q, sum = 0;
        scanf("%d", &q);
        while (q--)
        {
            int x, y, val;
            scanf("%d%d%d", &x, &y, &val);
            change(1,x, y, val);
        }
        sum = query(1);
        printf("Case %d: The total value of the hook is %d.\n", Case++,sum);
    }
}

猜你喜欢

转载自www.cnblogs.com/whhh/p/13374105.html