HDU 1689 Just a Hook (线段树, 区间修改)

2024-01-03 13:38
文章标签 修改 区间 hdu 线段 hook 1689

本文主要是介绍HDU 1689 Just a Hook (线段树, 区间修改),希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!


这道题 卡了我 长达 一个月之久, 从 树状数组 开始 就一直 WA,  简单的一道 线段树 区间修改模板题, 愣是让我 做了这么久 ,  线段树 区间 修改 延迟标记,!!!!!!!!!!!!

Just a Hook

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


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
  
1 10 2 1 5 2 5 9 3

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

反正题意 就是 让你求修改后 1-n 之间的和,  

线段树,   区间修改模板!!!;

注意的要点在于  

1 :延迟修改时    L 与 R  是 建立区间的 长度 而不是 修改区间的长度;

2 :数值修改时    L 与 R  是 建立区间的 长度 而不是 修改区间的长度;

3 : 要进行 向上更新 和向下更新,  并且 向下更新 一定要在  左右区间回溯之前,  向上更新 在 左右区间之后



我的代码:

#include <iostream>
#include <stdio.h>
#include <algorithm>
#include <cmath>
#include <cstring>
#include <string>
#include <queue>
#include <stack>
#include <stdlib.h>
#include <list>
#include <map>
#include <set>
#include <bitset>
#include <vector>
#define mem(a,b) memset(a,b,sizeof(a))
#define findx(x) lower_bound(b+1,b+1+bn,x)-b
#define FIN      freopen("input.txt","r",stdin)
#define FOUT     freopen("output.txt","w",stdout)
#define S1(n)    scanf("%d",&n)
#define S2(n,m)  scanf("%d%d",&n,&m)
#define Pr(n)     printf("%d\n",n)using namespace std;
typedef long long ll;
const double PI=acos(-1);
const int INF=0x3f3f3f3f;
const double esp=1e-6;
const int maxn=1e6+5;
const int MOD=1e9+7;
const int mod=1e9+7;
int dir[5][2]={0,1,0,-1,1,0,-1,0};struct SegTree{int val;int addmark;
}Seg[maxn<<2];void PushUP(int root)
{Seg[root].val=Seg[root<<1].val+Seg[root<<1|1].val;
}void build(int root,int l,int r)
{Seg[root].addmark=0;if(l==r){Seg[root].val=1;return;}int mid=(l+r)>>1;build(root<<1,l,mid);build(root<<1|1,mid+1,r);PushUP(root);
}
void PushDown(int root,int l,int r)
{if(Seg[root].addmark){Seg[root<<1].addmark=Seg[root<<1|1].addmark=Seg[root].addmark;Seg[root<<1].val=Seg[root].addmark*l;Seg[root<<1|1].val=Seg[root].addmark*r;Seg[root].addmark=0;}
}
void update(int root,int l,int r,int left,int right,int m)
{int mid=(l+r)>>1;if(left<=l&&right>=r){Seg[root].val=m*(r-l+1);Seg[root].addmark=m;return ;}PushDown(root,mid-l+1,r-mid);if(left<=mid)update(root<<1,l,mid,left,right,m);if(right>mid)update(root<<1|1,mid+1,r,left,right,m);PushUP(root);
}int main()
{int T;int n,m;//FIN;cin>>T;int cont=0;int x,y,z;while(T--){S1(n);build(1,1,n);S1(m);while(m--){scanf("%d%d%d",&x,&y,&z);update(1,1,n,x,y,z);}printf("Case %d: The total value of the hook is %d.\n",++cont,Seg[1].val);}
}



这篇关于HDU 1689 Just a Hook (线段树, 区间修改)的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/565875

相关文章

Docker镜像修改hosts及dockerfile修改hosts文件的实现方式

《Docker镜像修改hosts及dockerfile修改hosts文件的实现方式》:本文主要介绍Docker镜像修改hosts及dockerfile修改hosts文件的实现方式,具有很好的参考价... 目录docker镜像修改hosts及dockerfile修改hosts文件准备 dockerfile 文

Python实现无痛修改第三方库源码的方法详解

《Python实现无痛修改第三方库源码的方法详解》很多时候,我们下载的第三方库是不会有需求不满足的情况,但也有极少的情况,第三方库没有兼顾到需求,本文将介绍几个修改源码的操作,大家可以根据需求进行选择... 目录需求不符合模拟示例 1. 修改源文件2. 继承修改3. 猴子补丁4. 追踪局部变量需求不符合很

Linux修改pip和conda缓存路径的几种方法

《Linux修改pip和conda缓存路径的几种方法》在Python生态中,pip和conda是两种常见的软件包管理工具,它们在安装、更新和卸载软件包时都会使用缓存来提高效率,适当地修改它们的缓存路径... 目录一、pip 和 conda 的缓存机制1. pip 的缓存机制默认缓存路径2. conda 的缓

Linux修改pip临时目录方法的详解

《Linux修改pip临时目录方法的详解》在Linux系统中,pip在安装Python包时会使用临时目录(TMPDIR),但默认的临时目录可能会受到存储空间不足或权限问题的影响,所以本文将详细介绍如何... 目录引言一、为什么要修改 pip 的临时目录?1. 解决存储空间不足的问题2. 解决权限问题3. 提

Linux文件名修改方法大全

《Linux文件名修改方法大全》在Linux系统中,文件名修改是一个常见且重要的操作,文件名修改可以更好地管理文件和文件夹,使其更具可读性和有序性,本文将介绍三种在Linux系统下常用的文件名修改方法... 目录一、引言二、使用mv命令修改文件名三、使用rename命令修改文件名四、mv命令和rename命

mybatis-plus 实现查询表名动态修改的示例代码

《mybatis-plus实现查询表名动态修改的示例代码》通过MyBatis-Plus实现表名的动态替换,根据配置或入参选择不同的表,本文主要介绍了mybatis-plus实现查询表名动态修改的示... 目录实现数据库初始化依赖包配置读取类设置 myBATis-plus 插件测试通过 mybatis-plu

Linux下修改hostname的三种实现方式

《Linux下修改hostname的三种实现方式》:本文主要介绍Linux下修改hostname的三种实现方式,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录linux下修改ho编程stname三种方式方法1:修改配置文件方法2:hFvEWEostnamectl命

Git如何修改已提交人的用户名和邮箱

《Git如何修改已提交人的用户名和邮箱》文章介绍了如何修改Git已提交人的用户名和邮箱,包括注意事项和具体步骤,确保操作正确无误... 目录git修改已提交人的用户名和邮箱前言第一步第二步总结git修改已提交人的用户名和邮箱前言需注意以下两点内容:需要在顶层目录下(php就是 .git 文件夹所在的目

修改若依框架Token的过期时间问题

《修改若依框架Token的过期时间问题》本文介绍了如何修改若依框架中Token的过期时间,通过修改`application.yml`文件中的配置来实现,默认单位为分钟,希望此经验对大家有所帮助,也欢迎... 目录修改若依框架Token的过期时间修改Token的过期时间关闭Token的过期时js间总结修改若依

MySQL修改密码的四种实现方式

《MySQL修改密码的四种实现方式》文章主要介绍了如何使用命令行工具修改MySQL密码,包括使用`setpassword`命令和`mysqladmin`命令,此外,还详细描述了忘记密码时的处理方法,包... 目录mysql修改密码四种方式一、set password命令二、使用mysqladmin三、修改u