Just a Hook(线段树之点的成段更新)

萌萌哒的传送门

/*
 * hdu 1698
 * 线段树的点的成段更新
 * 这道题不用预先建树,只需把1号节点延迟标记下就行
 */
#include <iostream>
#include <cstring>
#include <cstdio>
#include <cmath>
#include <set>
#include <queue>
#include <vector>
#include <cstdlib>
#include <algorithm>

#define ls u << 1
#define rs u << 1 | 1
#define lson l, mid, u << 1
#define rson mid + 1, r, u << 1 | 1
#define INF 0x3f3f3f3f

using namespace std;
typedef long long ll;
const int M = 1e5 + 100;
int tmp[M << 2];

void pushdown(int u){
    if(tmp[u]){
        tmp[ls] = tmp[rs] = tmp[u];
        tmp[u] = 0;
    }
}

void pushup(int u){
    if(tmp[ls] == tmp[rs]){
        tmp[u] = tmp[ls];
    }
}

void update(int L,int R,int c,int l,int r,int u){
    int mid = (l + r) >> 1;
    if(L <= l && R >= r){
        tmp[u] = c;
    }
    else {
        pushdown(u);
        if(L <= mid) update(L,R,c,lson);
        if(R > mid) update(L,R,c,rson);
        pushup(u);
    }
}

int query(int l,int r,int u){
    int mid = (l + r) >> 1;
    if(tmp[u]){
        return (r - l + 1) * tmp[u];
    }
    else {
        int res = 0;
        res += query(lson);
        res += query(rson);
        return res;
    }
}

int main(){
    //freopen("in","r",stdin);
    int T,n,m,cnt = 0;
    cin>>T;
    while(T--){
        scanf("%d %d",&n,&m);
        tmp[1] = 1;
        while(m--){
            int l,r,c;
            scanf("%d %d %d",&l,&r,&c);
            update(l,r,c,1,n,1);
        }
        printf("Case %d: The total value of the hook is %d.\n",++cnt,query(1,n,1));
    }
    return 0;
}
时间: 2024-10-10 18:28:25

Just a Hook(线段树之点的成段更新)的相关文章

Mayor&#39;s posters(线段树之点的成段更新加离散化)

bin神的萌萌哒专题 这道题目也是简单区间更新的线段树题目,不过题目的数据范围很大,直接搞,时间空间的花费都会异常的高,所以就要用到离散化来优化时间空间复杂度. 何为离散化?........................ 简单地说就是对于给出的庞大数据进行一种数据上的缩小. 比如给你一段(1,10000)的区间,由于我们要的不是其区间长度,我们只需要知道这段区间的状态 如何,于是我们可以忽视其长度,把其表示成(1,2)这个区间长度极小的区间,这相当于物理上的质点. 当我们处理的问题上与其区间长

poj 4047 Garden 线段树lazy标记与成段更新

题意: 给长度为n的序列及k(0<k<=n<=200000),m个操作p,x,y.其中(1)p==0:将x位置处的数变为y;(2)p==1:将x,y位置处的数互换.(3)p==2查询x-y位置之间连续k个数的和的最大值. 分析: 求连续区间的和最大,可以把区间看成一个点,这样这n-k+1个区间的最大和可以看做n-k+1个点的最大值,当更新原序列中位置x的值就相当于更新区间中x-k+1到x区间的值,然后用线段树做成段更新.成段更新要用到lazy标记,我的理解是:当更新或query的时候如果

线段树(多维+双成段更新) UVA 11992 Fast Matrix Operations

题目传送门 题意:训练指南P207 分析:因为矩阵不超过20行,所以可以建20条线段的线段树,支持两个区间更新以及区间查询. #include <bits/stdc++.h> using namespace std; #define lson l, mid, o << 1 #define rson mid + 1, r, o << 1 | 1 typedef long long ll; const int INF = 0x3f3f3f3f; const int N =

HDU--1698(线段树,区间修改成段替换)

Just a Hook Time Limit: 2000MS   Memory Limit: 32768KB   64bit IO Format: %I64d & %I64u Submit Status 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 consec

HDU1698 Just a Hook 【线段树】+【成段更新】+【lazy标记】

Just a Hook Time Limit: 4000/2000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) Total Submission(s): 15889    Accepted Submission(s): 7897 Problem Description In the game of DotA, Pudge's meat hook is actually the most horrible thing

Hdu1698Just a Hook线段树区间更新

区间更新基础..不说了,也是照着notonlysuccess的博客撸的. #include <cstdio> #include <cstring> #include <algorithm> #include <climits> #include <string> #include <iostream> #include <map> #include <cstdlib> #include <list>

线段树(成段更新) HDU 1698 Just a Hook

题目传送门 1 /* 2 线段树-成段更新:第一题!只要更新区间,输出总长度就行了 3 虽然是超级裸题,但是用自己的风格写出来,还是很开心的:) 4 */ 5 #include <cstdio> 6 #include <algorithm> 7 #include <cmath> 8 #include <cstring> 9 #include <string> 10 #include <iostream> 11 using namesp

HDU - 1698 - Just a Hook (线段树-成段更新)

题目传送:Just a Hook 思路:线段树,成段替换, 区间求和.成段更新时,注意延迟标记的作用,它就是用来暂停往下更新来达到节省时间的,然后每次更新每个节点的子节点之前都要判断是否需要往下更新. AC代码: #include <cstdio> #include <cstring> #include <iostream> #include <algorithm> #include <cmath> #include <queue>

hdu1698Just a Hook 线段树 成段更新水题

//简单的线段树,注意成段更新,以免超时 #include<iostream> #include<cstdio> #include<cstring> using namespace std ; const int maxn = 100010 ; struct node { int value ; int r , l; int flag ;//记录到当前区间的状态 }tree[maxn<<2] ; void build(int l , int r ,int v