Just a Hook (HDU_1698) 线段树+区间更新
2016-02-02 10:42
337 查看
Just a Hook
Time Limit: 4000/2000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)Total Submission(s): 24870 Accepted Submission(s): 12411
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.
Source
2008 “Sunline Cup” National Invitational Contest
题目大意:给定n个数,进行q次区间更新,求这n个数的总和
解题思路:线段树,区间更新。
代码如下:
#include"iostream" #include"cstdio" #define ll __int64 using namespace std; //线段树的最大节点数 const ll maxn=110000; //线段数定义 struct Tree{ ll l,r,sum,add; ll getmid(){ //返回线段的中点 return (l+r)>>1; } }tree[4*maxn]; //向上一层推 void pushup(ll x){ ll tmp=2*x; tree[x].sum=tree[tmp].sum+tree[tmp+1].sum; } //向下一层推 void pushdown(ll x){ ll tmp=2*x; tree[tmp].add=tree[x].add; tree[tmp+1].add=tree[x].add; tree[tmp].sum=tree[x].add*(tree[tmp].r-tree[tmp].l+1); tree[tmp+1].sum=tree[x].add*(tree[tmp+1].r-tree[tmp+1].l+1); tree[x].add=0; } //构建线段树 void Build(ll l,ll r,ll x){ tree[x].l=l; tree[x].r=r; tree[x].add=0; if(tree[x].l==tree[x].r){ //叶子节点 tree[x].sum=1; return ; } ll mid=tree[x].getmid(); ll tmp=2*x; Build(l,mid,tmp); //向左子树递归 Build(mid+1,r,tmp+1); //向右子树递归 pushup(x); //在回溯时向上推 } //区间更新 void Updata(ll l,ll r,ll x,ll c){ //所更新区间【l,r】,增加值c,当前节点x if(tree[x].l>r||tree[x].r<l) //节点包含区间,不在更新区间内 return ; if(l<=tree[x].l&&tree[x].r<=r){ //节点包含区间包含于更新区间 tree[x].add=c; tree[x].sum=c*(tree[x].r-tree[x].l+1); return ; } if(tree[x].add!=0) pushdown(x); //在抵达新一轮更新区间前,将新的值向下传达 ll tmp=2*x; Updata(l,r,tmp,c); Updata(l,r,tmp+1,c); pushup(x); } //区间查询 ll ans; //存储查询答案 void Query(ll l,ll r,ll x){ //【l,r】为当前查询区间,x为当前节点 if(tree[x].l>r||tree[x].r<l) //节点包含区间不在查询区间 return ; if(l<=tree[x].l&&tree[x].r<=r){ //节点区间包含于查询区间 ans+=tree[x].sum; return ; } ll mid=tree[x].getmid(); ll tmp=2*x; if(r<=mid) //当前查询区间在节点的左半区间 Query(l,r,tmp); else if(l>mid) //当前查询区间在节点的右半区间 Query(l,r,tmp+1); else{ //查询区间分布在节点的左右区间 Query(l,mid,tmp); Query(mid+1,r,tmp+1); } } //主函数 int main(){ int T; scanf("%d",&T); for(int i=1;i<=T;i++){ ll n,q; scanf("%I64d %I64d",&n,&q); ans=0; Build(1,n,1); ll x,y,c; while(q--){ scanf("%I64d %I64d %I64d",&x,&y,&c); Updata(x,y,1,c); } Query(1,n,1); printf("Case %d: The total value of the hook is %I64d.\n",i,ans); } return 0; }
相关文章推荐
- 初学ACM - 组合数学基础题目PKU 1833
- 线段树题集
- POJ ACM 1001
- POJ ACM 1002
- 1611:The Suspects
- POJ1089 区间合并
- POJ 2635 The Embarrassed Cryptographe
- POJ 3292 Semi-prime H-numbers
- POJ 2773 HAPPY 2006
- POJ 3090 Visible Lattice Points
- POJ-2409-Let it Bead&&NYOJ-280-LK的项链
- POJ-1695-Magazine Delivery-dp
- POJ1523 SPF dfs
- POJ-1001 求高精度幂-大数乘法系列
- POJ-1003 Hangover
- POJ-1004 Financial Management
- 用单调栈解决最大连续矩形面积问题
- 线段树
- 2632 Crashing Robots的解决方法
- 1573 Robot Motion (简单题)