Hdu1698 Just a Hook(线段树成段更新)

题意很简单:1-n个钩子初始价值是1,然后题目给出Q个操作,x
y z,将x->y的钩子价值改为z,最后输出n个钩子的总价值。

线段树功能:update:成段替换 (由于只query一次总区间,所以可以直接输出1结点的信息)

//3160 KB 624 ms
#include<cstdio>
#include<iostream>
#include<cstring>
#include<algorithm>
#define M 100005
#define root 1,n,1
#define lson l,m,rt<<1
#define rson m+1,r,rt<<1|1
using namespace std;
int sum[M<<2];
int col[M<<2];
void pushup(int rt)
{
    sum[rt]=sum[rt<<1]+sum[rt<<1|1];
}
void pushdown(int rt,int m)
{
    if(!col[rt]) return;
    col[rt<<1]=col[rt<<1|1]=col[rt];
    sum[rt<<1]=col[rt]*(m-(m>>1)); //m-m/2是左儿子的区间长度
    sum[rt<<1|1]=col[rt]*(m>>1); //m/2 是右儿子的区间长度
	/*可以化简成 这样简单表示左右儿子区间长度的方式,而且左儿子的区间长度>=右儿子的,这样记忆便可*/
    col[rt]=0;
}
void build(int l,int r,int rt)
{
    col[rt]=0;
    if(l==r){
        sum[rt]=1;
        return ;
    }
    int m=(l+r) >>1;
    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){
        sum[rt]=c*(r-l+1);
        col[rt]=c;
        return;
    }
    pushdown(rt,r-l+1); //pushdown lazytag
    int m=(l+r)>>1;
    if(L<=m) update(L,R,c,lson);
    if(R>m) update(L,R,c,rson);
    pushup(rt);
}
int main()
{
    int cas,n,m;
    scanf("%d",&cas);
    for(int k=1;k<=cas;k++){
        scanf("%d%d",&n,&m);
        build(root);
        for(int j=1;j<=m;j++){
            int a,b,c;
            scanf("%d%d%d",&a,&b,&c);
            update(a,b,c,root);
        }
        printf("Case %d: The total value of the hook is %d.\n",k,sum[1]);
    }
    return 0;
}
时间: 2025-01-14 17:17:24

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

HDU 1698 Just a Hook (线段树 成段更新 lazy-tag思想)

题目链接 题意: n个挂钩,q次询问,每个挂钩可能的值为1 2 3,  初始值为1,每次询问 把从x到Y区间内的值改变为z.求最后的总的值. 分析:用val记录这一个区间的值,val == -1表示这个区间值不统一,而且已经向下更新了, val != -1表示这个区间值统一, 更新某个区间的时候只需要把这个区间分为几个区间更新就行了, 也就是只更新到需要更新的区间,不用向下更新每一个一直到底了,在更新的过程中如果遇到之前没有向下更新的, 就需要向下更新了,因为这个区间的值已经不统一了. 其实这就

HDU1698_Just a Hook(线段树/成段更新)

解题报告 题意: 原本区间1到n都是1,区间成段改变成一个值,求最后区间1到n的和. 思路: 线段树成段更新,区间去和. #include <iostream> #include <cstdio> #include <cstring> using namespace std; int sum[500000],lz[500000]; void push_up(int root,int l,int r) { sum[root]=sum[root*2]+sum[root*2+

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

hdu 1698 Just a Hook 线段树成段更新

线段树功能:update:成段替换 成段更新去要用到延迟标记,具体调试代码就容易懂些 #include <iostream> #include <string> #include <cstdio> #define lson l, m, rt<<1 #define rson m+1, r, rt<<1|1 using namespace std; const int MAXN = 111111; int sum[MAXN<<2], ch

线段树(成段更新) 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

题意:给出n根金属棒,和操作数q,初始时每个金属棒价值都为1,每次操作可以把从x到y的金属棒更换材质,铜为1,银为2,金为3,最后统计所有的金属棒总价值是多少. 线段树成段更新,需要用到lazy标记,所谓lazy标记就是:更新一个区间的时候不更新到底,只更新到第一个满足更新范围的区间(即范围内的最大的区间),然后给节点加上lazy标记,以后需要更新到该节点的子节点的时候,就把lazy标记转移到子节点上,这样大大提升了效率. 代码:

Codeforces Round #149 (Div. 2) E. XOR on Segment (线段树成段更新+二进制)

题目链接:http://codeforces.com/problemset/problem/242/E 给你n个数,m个操作,操作1是查询l到r之间的和,操作2是将l到r之间的每个数xor与x. 这题是线段树成段更新,但是不能直接更新,不然只能一个数一个数更新.这样只能把每个数存到一个数组中,长度大概是20吧,然后模拟二进制的位操作.仔细一点就行了. 1 #include <iostream> 2 #include <cstdio> 3 #include <cmath>

POJ 2777 Count Color (线段树成段更新+二进制思维)

题目链接:http://poj.org/problem?id=2777 题意是有L个单位长的画板,T种颜色,O个操作.画板初始化为颜色1.操作C讲l到r单位之间的颜色变为c,操作P查询l到r单位之间的颜色有几种. 很明显的线段树成段更新,但是查询却不好弄.经过提醒,发现颜色的种类最多不超过30种,所以我们用二进制的思维解决这个问题,颜色1可以用二进制的1表示,同理,颜色2用二进制的10表示,3用100,....假设有一个区间有颜色2和颜色3,那么区间的值为二进制的110(十进制为6).那我们就把

POJ 2528 Mayor&#39;s posters (hash+线段树成段更新)

题意:有一面墙,被等分为1QW份,一份的宽度为一个单位宽度.现在往墙上贴N张海报,每张海报的宽度是任意的,但是必定是单位宽度的整数倍,且<=1QW.后贴的海报若与先贴的海报有交集,后贴的海报必定会全部或局部覆盖先贴的海报.现在给出每张海报所贴的位置(左端位置和右端位置),问张贴完N张海报后,还能看见多少张海报?(PS:看见一部分也算看到.) 思路:简单的成段更新,但是数据量是1千万,会MT,所以要区间压缩(离散化),保证覆盖的关系不变,离散化的时候有个易错的细节,poj数据水了,这个易错点引用h

POJ训练计划2777_Count Color(线段树/成段更新/区间染色)

解题报告 题意: 对线段染色,询问线段区间的颜色种数. 思路: 本来直接在线段树上染色,lz标记颜色.每次查询的话访问线段树,求出颜色种数.结果超时了,最坏的情况下,染色可以染到叶子节点. 换成存下区间的颜色种数,这样每次查询就不用找到叶子节点了,用按位或来处理颜色种数. #include <iostream> #include <cstdio> #include <cstring> #include <algorithm> using namespace