Just a Hook

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

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,然后每次使x到y间的钩子变为银2,或金3;线段树;
错了很多次,原来想着把z设为全局变量,最后答案一直不对,经历了各种曲折。。。
代码:
 1 #include<stdio.h>
 2 const int MAXN=100010;
 3 struct Node{
 4     int l,r;
 5     int sum,lazy,val;//val不能全局变量。。。
 6 };
 7 Node tree[MAXN<<2];
 8 #define NOW tree[root].sum=tree[root<<1].sum+tree[root<<1|1].sum
 9 #define lson root<<1,tree[root].l,mid
10 #define rson root<<1|1,mid+1,tree[root].r
11 void build(int root,int l,int r){
12     tree[root].l=l;
13     tree[root].r=r;
14     tree[root].lazy=0;
15     tree[root].val=0;
16     if(l==r)tree[root].sum=1;
17     else{
18             int mid=(l+r)>>1;
19         build(lson);
20         build(rson);
21         NOW;
22     }
23 }
24 void update(int root,int l,int r,int v){
25     if(l==tree[root].l&&r==tree[root].r){
26             tree[root].lazy=1;
27             tree[root].val=v;
28             tree[root].sum=(r-l+1)*v;
29     }
30     else{
31         int mid=(tree[root].l+tree[root].r)>>1;
32         if(tree[root].lazy==1){
33             tree[root].lazy=0;
34             update(lson,tree[root].val);
35             update(rson,tree[root].val);
36             tree[root].val=0;
37         }
38         if(r<=mid)update(root<<1,l,r,v);
39         else if(l>mid)update(root<<1|1,l,r,v);
40         else{//这个不能少了,代表l,r在tree的两个孩子节点内,也就是找到了l,r的区间;
41             update(root<<1,l,mid,v);
42             update(root<<1|1,mid+1,r,v);
43         }
44         NOW;
45     }
46 }
47 int main(){
48     int T,N,Q,flot=0;
49     scanf("%d",&T);
50     while(T--){
51             scanf("%d",&N);
52         scanf("%d",&Q);
53         build(1,1,N);
54         while(Q--){
55             int x,y,z;
56             scanf("%d%d%d",&x,&y,&z);
57             update(1,x,y,z);
58         }
59         printf("Case %d: The total value of the hook is %d.\n",++flot,tree[1].sum);
60     }
61     return 0;
62 }

过了一段时间又写了一遍,增强了自己的理解:

代码:

#include<iostream>
#include<cstdio>
#include<cstring>
#include<cmath>
#include<vector>
#include<algorithm>
#include<set>
using namespace std;
#define mem(x,y) memset(x,y,sizeof(x))
const int MAXN=100010;
struct Node{int lazy,v;
};
Node tree[MAXN<<2];
#define ll root<<1
#define rr root<<1|1
#define lson ll,l,mid
#define rson rr,mid+1,r
#define LAZY(x) tree[x].lazy
#define V(x) tree[x].v
int ans;
void pushdown(int root,int x){if(LAZY(root)){LAZY(ll)=LAZY(root);LAZY(rr)=LAZY(root);V(ll)=LAZY(root)*(x-(x>>1));//这里错了半天。。。。。右节点有时候要多一。。。 V(rr)=LAZY(root)*(x>>1);LAZY(root)=0;}
}
void pushup(int root){V(root)=V(ll)+V(rr);
}
void build(int root,int l,int r){LAZY(root)=0;int mid=(l+r)>>1;if(l==r){V(root)=1;return;}build(lson);build(rson);pushup(root);
}
void update(int root,int l,int r,int L,int R,int v){if(l>=L&&r<=R){LAZY(root)=v;V(root)=(r-l+1)*v;return;}pushdown(root,r-l+1);int mid=(l+r)>>1;/*if(mid>=R)update(lson,L,R,v);else if(mid<L)update(rson,L,R,v);else{update(lson,L,mid,v);update(rson,mid+1,R,v);}*///这样写也可以。。。 if(mid>=L)update(lson,L,R,v);if(mid<R)update(rson,L,R,v); pushup(root);
}
void query(int root,int l,int r,int L,int R){int mid=(l+r)>>1;if(l>=L&&r<=R){ans+=V(root);return;}pushdown(root,r-l+1);if(mid>=L)query(lson,L,R);if(mid<R)query(rson,L,R);
}
int main(){int T,N,kase=0;scanf("%d",&T);while(T--){scanf("%d",&N);build(1,1,N);int q,a,b,c;scanf("%d",&q);while(q--){scanf("%d%d%d",&a,&b,&c);update(1,1,N,a,b,c);}ans=0;query(1,1,N,1,N);//也可以不询问直接输出tree[1].v printf("Case %d: The total value of the hook is %d.\n",++kase,ans);}return 0;
}

  map超时;

代码:

#include<iostream>
#include<cstdio>
#include<map>
#include<algorithm>
using namespace std;
map<int,int>mp;
map<int,int>::iterator it1;
const int MAXN=100010;
struct Node{int s,e,v;
};
Node dt[MAXN];
int main(){int T,N,q,kase=0;scanf("%d",&T);while(T--){scanf("%d",&N);for(int i=1;i<=N;i++)mp[i]=1;scanf("%d",&q);for(int i=0;i<q;i++)scanf("%d%d%d",&dt[i].s,&dt[i].e,&dt[i].v);for(int i=0;i<q;i++){for(it1=mp.lower_bound(dt[i].s);it1!=mp.end();){if(it1->first<=dt[i].e)it1->second=dt[i].v,it1++;else break;}}int ans=0;for(int i=1;i<=N;i++)ans+=mp[i];printf("Case %d: The total value of the hook is %d.\n",++kase,ans);}return 0;
}

   过了一段时间又写了遍,本想着一遍a的,但是错了几个小时,实在找不出,问了群里面的大神,原来我是x-(x>>1)没有加括号,这就是代码风格的问题了,我的代码风格存在很大的问题,以至于错误了很难找出来,大神指出了几点问题:

1:关于define 的括号问题;

2:关于字母与运算符的缩进问题;

3:关于宏定义的名称问题;都存在一定问题;以后要注意了,参照谷歌的吧

另一种线段树写法:

extern "C++"{
#include<iostream>
#include<cstdio>
#include<cstring>
#include<cmath>
#include<algorithm>
using namespace  std;
typedef long long LL;
typedef unsigned u;
typedef unsigned long long ull;
#define mem(x,y) memset(x,y,sizeof(x))
void SI(double &x){scanf("%lf",&x);}
void SI(int &x){scanf("%d",&x);}
void SI(LL &x){scanf("%lld",&x);}
void SI(u &x){scanf("%u",&x);}
void SI(ull &x){scanf("%llu",&x);}
void SI(char *s){scanf("%s",s);}void PI(int x){printf("%d",x);}
void PI(double x){printf("%lf",x);}
void PI(LL x){printf("%lld",x);}
void PI(u x){printf("%u",x);}
void PI(ull x){printf("%llu",x);}
void PI(char *s){printf("%s",s);}#define NL puts("");
#define ll root<<1
#define rr root<<1|1
#define lson ll,l,mid
#define rson rr,mid+1,r
const int INF=0x3f3f3f3f;
const int MAXN=100010;
int tree[MAXN<<2];
int lazy[MAXN<<2];
}
/*
void pushup(int root){tree[root]=tree[ll]+tree[rr];
}
void pushdown(int root,int x){if(lazy[root]){lazy[ll]=lazy[root];lazy[rr]=lazy[root];//    tree[ll]=lazy[root]*(mid-l+1);//    tree[rr]=lazy[root]*(r-mid);tree[ll]=lazy[root]*(x-(x>>1));tree[rr]=lazy[root]*(x>>1);lazy[root]=0;}
}
void build(int root,int l,int r){int mid=(l+r)>>1;lazy[root]=0;if(l==r){tree[root]=1;return ;}build(lson);build(rson);pushup(root);
}
void update(int root,int l,int r,int L,int R,int C){if(l>=L&&r<=R){tree[root]=(r-l+1)*C;lazy[root]=C;return ;}int mid=(l+r)>>1;pushdown(root,r-l+1);if(mid>=L)update(lson,L,R,C);if(mid<R)update(rson,L,R,C);pushup(root);
}
*/
void pushdown(int root){lazy[ll] = lazy[rr] = lazy[root];lazy[root] = 0;
}
void update(int root,int l,int r,int L,int R,int C){if(l >= L && r <= R){lazy[root] = C;return;}if(lazy[root])pushdown(root);int mid = (l + r) >> 1;if(mid >= L)update(lson,L,R,C);if(mid < R)update(rson,L,R,C);
}
int sum(int root,int l,int r){int mid = (l + r) >> 1;if(lazy[root])return (r - l + 1) * lazy[root];return sum(lson) + sum(rson);
}
int main(){//assert(false);int T,kase=0;int N,M;SI(T);while(T--){SI(N);lazy[1]=1;SI(M);int a,b,c;while(M--){scanf("%d%d%d",&a,&b,&c);update(1,1,N,a,b,c);}printf("Case %d: The total value of the hook is %d.\n",++kase,sum(1,1,N));}return 0;
}

java超时了。。。

注意:左右查找都是mid判断的。。。注意lazy要把左右支lazy

代码:

import java.util.Scanner;public class hdoj1698{public static void main(String[] argv){Scanner cin = new Scanner(System.in);SegmentTree atree = new SegmentTree(100010 << 2);int T, N, q;T = cin.nextInt();int kase = 0;while(T-- > 0){N = cin.nextInt();atree.build(1, 1, N);q = cin.nextInt();while(q-- > 0){int a, b, c;a = cin.nextInt();b = cin.nextInt();c = cin.nextInt();atree.update(1, 1, N, a, b, c);}//    System.out.println(atree.tree[1]);
            System.out.println("Case " + (++kase) + ": The total value of the hook is " + atree.query(1, 1, N, 1, N) + ".");}}
}class SegmentTree{private int[] tree;private int[] lazy;public SegmentTree(int size) {tree = new int[size];lazy = new int[size];}private void pushup(int root){tree[root] = tree[root << 1] + tree[root<<1 | 1];}private void pushdown(int root, int x){if(lazy[root] != 0){lazy[root << 1] = lazy[root << 1|1] = lazy[root];tree[root << 1] = (x - (x >> 1))*lazy[root];tree[root << 1|1] = (x >> 1)*lazy[root];lazy[root] = 0;}}public void build(int root, int l, int r){lazy[root] = 0;if(l == r){tree[root] = 1;return ;}int mid = (l + r) >> 1;build(root << 1, l, mid);build(root << 1|1, mid + 1, r);pushup(root);}public void update(int root, int l, int r, int L, int R, int v){if(l >= L && r <= R){tree[root] = (r - l + 1)*v;lazy[root] = v;return;}pushdown(root, r - l + 1);int mid = (r + l) >> 1;if(mid >= L){update(root << 1, l, mid, L, R, v);}if(mid < R){update(root << 1|1, mid + 1, r, L, R, v);//日了狗了。。。。。。。。。。
        }pushup(root);}public int query(int root, int l, int r, int L, int R){if(l >= L && r <= R){return tree[root];}pushdown(root, r - l + 1);int sum = 0;int mid = (l + r) >> 1;if(mid >= L){sum += query(root << 1, l, mid, L, R);}if(mid < R){sum += query(root << 1|1, mid +1, r, L, R);}return sum;}}

转载于:https://www.cnblogs.com/handsomecui/p/4814792.html

魔兽世界---屠夫(Just a Hook)相关推荐

  1. HDU-1698 JUST A HOOK 线段树

    最近刚学线段树,做了些经典题目来练手 Just a Hook Time Limit: 4000/2000 MS (Java/Others) Memory Limit: 32768/32768 K (J ...

  2. 【HDU - 1698】 Just a Hook(线段树模板 区间覆盖更新(laz标记) + 区间和查询 )

    题干: In the game of DotA, Pudge's meat hook is actually the most horrible thing for most of the heroe ...

  3. HDOJ 1698 Just a Hook(线段树成段更新)

    题意: 屠夫的钩子区间是1~n,每段可能由铜,银,金组成,价值分别为1,2,3,进行一系列的更新之后,求钩子的总价值. 思路: 线段树的成段更新:要设置一个临时的线段树,每次更新的时候把更新段的值放在 ...

  4. HDU 1698 Just a Hook(线段树区间更新)

    题意: 屠夫是Dota中一个令所有英雄闻风丧胆的英雄.他有一个很长的钩子,这个钩子是用铜做的(刚刚开始都是1),现在他想要更改这些钩子,把某个区间的钩子改为金.银或铜. 输入 L, R, X 表示把 ...

  5. 让AI帮你玩游戏(一) 基于目标检测用几个样本帮你实现在魔兽世界中钓鱼(群已满)

    让AI帮你玩游戏 让AI帮你玩游戏(一) 基于目标检测用几个样本实现在魔兽世界中钓鱼 前言 思路 环境 获取图像(几个样本即可) 标记图片 从标记文件中获取Boxes坐标 搭建目标检测模型 准备训练数 ...

  6. PyTorch 学习笔记(六):PyTorch hook 和关于 PyTorch backward 过程的理解 call

    您的位置 首页 PyTorch 学习笔记系列 PyTorch 学习笔记(六):PyTorch hook 和关于 PyTorch backward 过程的理解 发布: 2017年8月4日 7,195阅读 ...

  7. 在React Hook里使用history.push跳转

    在React Hook里使用history.push跳转 react hook里用不了this.props.history的解决方法 首先引入 import { useHistory } from ' ...

  8. 在react hook里使用mobx(配置mobx依赖)

    在powershell里安装依赖 (直接npm i mobx或者npm i mobx-react是会报错的) npm i mobx mobx-react --save save是下载到"de ...

  9. HDU-1698-Just a Hook

    HDU-1698-Just a Hook http://acm.hdu.edu.cn/showproblem.php?pid=1698 还是成段更新线段树 #include<stdio.h> ...

最新文章

  1. 教你如何运用可视化理解卷积神经网络(CNNs)的指南
  2. mysql 存储过程循环一张表的所有记录_MySQL数据库知识汇总
  3. KUKA通信 CREAD问题
  4. AServer - 基于Asp.net core Kestrel的超迷你http服务器
  5. python输出文本内容_python 打印文件里的内容
  6. 闭包的示例_用示例解释JavaScript中的闭包
  7. 第一课~Django~简介
  8. JavaScript内置对象之Array对象总结(附实例)
  9. Fiddler中文使用教程-AutoResponder
  10. 宇宙最强下载器:IDM 俄罗斯大神版
  11. EPLAN p8 安装失败解决办法
  12. python3 numpy教程_Python Numpy 教程
  13. select函数使用细节
  14. 【计算机硬件系统设计(华科)——存储器设计(Logisim 实现)】
  15. 软考高项 - 计算公式汇总整理
  16. java 随机发牌_java实现扑克牌发牌器
  17. 识别以及生成二维码(长按扫面方式)
  18. 阿里云计算重磅公布云原生裸金属方法:裸金属+容器,此方法解锁云计算的新方式
  19. TureType/OpenType, TTF, OTF, TTC
  20. NT5/NT6上的获取进程全路径

热门文章

  1. 买卖股票的最佳时机II
  2. string学习笔记1
  3. C 语言实现数组冒泡排序
  4. [BUUCTF-pwn]——picoctf_2018_echo back
  5. [BUUCTF-pwn]——[HarekazeCTF2019]baby_rop
  6. 最小径集的算法_如何为数据集选择正确的聚类算法?
  7. EHCache 初步使用指南
  8. Transaction rolled back because it has been marked as rollback-only
  9. JAG Practice Contest for ACM-ICPC Asia Regional 2016.K.Non-redundant Drive(点分治)
  10. Zabbix安装(server和agent)及基本配置