数据结构&图论 B - Just a Hook

B - Just a Hook

题目链接:HDU1698
在这里插入图片描述

题解

思路

题目要求输出最终所有棒子的值的和。
由题意,初始化的棒子全为1,之后会对某一区间内的棒子值进行修改。此处的修改并非单纯地使得区间内的所有数字增减某一个值,所以不能使用差分数组。
由于修改次数比较多,且每一个点都可能在多个区间内,考虑了扫描线之后发现有点烦(懒.jpg)。
所以还是用线段树吧~

实现

线段树的使用一般都是板子题。
该题需要对线段树的实现做出一点点修改。
首先,在更新区间值的地方,不再是增减,而是改变。其次是懒惰标记的传递函数,当前节点的值为当前懒惰标记的值乘以以该节点为根节点的树的叶子节点数。
最后大胆地写板子吧~

AC代码

#include<iostream>
#include<cstdio>
#include<cstring>
#include<cmath>
#include<algorithm>
#include<cstdlib>
#include<string>
#include<queue>
#include<map>
#include<stack>
#include<list>
#include<set>
#include<deque>
#include<vector>
#include<ctime>

using namespace std;
//#pragma GCC optimize(2)
#define IO ios::sync_with_stdio(false);cin.tie(0);cout.tie(0)
#define ull unsigned long long
#define ll long long
#define rep(i, x, y) for(int i=x;i<=y;i++)
#define mms(x, n) memset(x, n, sizeof(x))
#define mmc(a, b) memcpy(a, b, sizeof(b))
#define INF (0x3f3f3f3f)
#define mod (ull)(1e9+7)
typedef pair<int, int> P;

namespace FastIO {
    const int bufsiz = 1 << 22;
    char buf[bufsiz];

    inline char getch() {
        static int tot;
        tot++;
        if (tot == bufsiz) {
            fread(buf, 1, bufsiz, stdin);
            tot = 0;
        }
        return buf[tot];
    }

    inline int read() {
        int x = 0;
        char c = getch();
        while (!isdigit(c))c = getch();
        while (isdigit(c))x = x * 10 + c - '0', c = getch();
        return x;
    }
}
using FastIO::read;
const int N = 1e5 + 10;
int n, m;
int Sum[N * 4], Add[N * 4];
int Num[N * 4];

void pushUp(int rt) {
    Sum[rt] = Sum[rt << 1] + Sum[rt << 1 | 1];
}

void buildTree(int l, int r, int rt) {
    if (l == r) {
        Sum[rt] = 1;
        Num[rt] = Sum[rt];
        return;
    }
    int mm = (l + r) >> 1;
    buildTree(l, mm, rt << 1);
    buildTree(mm + 1, r, rt << 1 | 1);
    pushUp(rt);
    Num[rt] = Sum[rt];
}

void pushDown(int rt) {
    if (Add[rt]) {
        Add[rt << 1] = Add[rt];
        Add[rt << 1 | 1] = Add[rt];
        Sum[rt << 1] = Add[rt] * Num[rt << 1];
        Sum[rt << 1 | 1] = Add[rt] * Num[rt << 1 | 1];
        Add[rt] = 0;
    }
}

void upDate(int L, int R, int l, int r, int w, int rt) {
    if (L <= l && r <= R) {
        Sum[rt] = w * (r - l + 1);
        Add[rt] = w;
        return;
    }
    int mm = (l + r) >> 1;
    pushDown(rt);
    if (L <= mm) upDate(L, R, l, mm, w, rt << 1);
    if (R > mm) upDate(L, R, mm + 1, r, w, rt << 1 | 1);
    pushUp(rt);
}

int main() {
//    freopen("input.txt", "r", stdin);
//    freopen("output.txt", "w", stdout);
    int T;
    scanf("%d", &T);
    rep(tt, 1, T) {
        mms(Add, 0);
        mms(Sum, 0);
        scanf("%d%d", &n, &m);
        buildTree(1, n, 1);
        while (m--) {
            int a, b, w;
            scanf("%d%d%d", &a, &b, &w);
            upDate(a, b, 1, n, w, 1);
        }
        printf("Case %d: The total value of the hook is %d.\n", tt, Sum[1]);
    }
    return 0;
}

猜你喜欢

转载自blog.csdn.net/qq_45934120/article/details/107731452
今日推荐