hdu 1698 Just a Hook

来源:互联网 发布:侠盗飞车3罪恶都市mac 编辑:程序博客网 时间:2024/04/30 16:45

Just a Hook

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


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
11021 5 25 9 3
 

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

AC代码:

//区间更新 /*      题意:一个棍子有可分为连续的N段,每一段的材料可能为金银铜,数值对应3,2,1,一开始材料为铜,所以棍子的价值就是N。然后进行修改操作,每次把区间[x,y]的每个单元都变为数值z。z的值为1,2,3。所有的修改操作做完后,输出子的价值本题用到lazy标志,可以节省时间减少操作。例如棍子为10段,要更新区间[1,5]为2,这样就不需要更新到每一个叶子节点,用lazy来做标记,lazy分为0,1,2,3。0表示区间内的叶子节点值不同,1,2,3表示叶子节点为1,2,3,也就是说在这段区间内材料是相同的 */ #include<bits/stdc++.h>using namespace std;#define lson l,m,x<<1#define rson m+1,r,x<<1|1#define size 100001struct node{int l,r;     //用来记录区间的两端int sum;     //记录区间和int lazy;    //用做标记 }tree[size<<2];void sum(int x){tree[x].sum=tree[x<<1].sum+tree[x<<1|1].sum;} void build(int l,int r,int x){tree[x].l=l;       //区间左端点 tree[x].r=r;       //区间右端点 tree[x].lazy=1;    //初始时,材料为铜,所以为1 if(l==r){tree[x].sum=1;return;}int m=(tree[x].l+tree[x].r)>>1;build(lson);build(rson);sum(x);}void update(int l,int r,int x,int up){if(tree[x].lazy==up)return;      //如果要更新的和元的材料一样,就不用更新了 if(tree[x].l==l&&tree[x].r==r){  //如果刚好是一个子区间,这样简化操作 tree[x].lazy=up;tree[x].sum=(r-l+1)*up;return;}if(tree[x].lazy){                //如果不符合上面的两种条件,就需要更新子区间了 tree[x<<1].lazy=tree[x<<1|1].lazy=tree[x].lazy;   //此时左儿子和右儿子的lazy一定和父亲一样 tree[x<<1].sum=(tree[x<<1].r-tree[x<<1].l+1)*tree[x].lazy;  //求左儿子的和 tree[x<<1|1].sum=(tree[x<<1|1].r-tree[x<<1|1].l+1)*tree[x].lazy;   //求右儿子的和tree[x].lazy=0;              //更新标记为0.因为下面要更新改变儿子的lazy }int m=(tree[x].l+tree[x].r)>>1;/*     找到要更新的两个叶子区间 */if(l>m)update(l,r,x<<1|1,up);    //去右区间找 else if(r<=m)update(l,r,x<<1,up);//去左区间找else{                            //横跨两个区间此时更新 update(lson,up);update(rson,up);}sum(x);}int main(){int T,N,Q;int a,b;int val;while(~scanf("%d",&T)){for(int i=1;i<=T;i++){scanf("%d",&N);build(1,N,1);scanf("%d",&Q);while(Q--){scanf("%d %d %d",&a,&b,&val);update(a,b,1,val); }printf("Case %d: The total value of the hook is %d.\n",i,tree[1].sum);}}return 0;}  


 
0 0