HDU-1698-Just a Hook(Lazy算法)

来源:互联网 发布:云计算工程师做什么 编辑:程序博客网 时间:2024/06/08 10:14

E - Just a Hook
Time Limit:2000MS Memory Limit:32768KB 64bit IO Format:%I64d & %I64u
Submit

Status

Practice

HDU 1698
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.

题意:首行给出T,代表T组测试数据。每组测试数据第一行给出N,代表有1到N个钩子,每个钩子初始价值为1。第二行给出Q,代表有Q组操作。接着Q行,每行给出X,Y,Z,代表把X到Y区间钩子的价值更改为Z。最后输出1到N所有钩子的总价值。

思路:线段树的延迟更新,裸的Lazy

代码

#include<stdio.h>#include<iostream>#include<algorithm>#include<string.h>using namespace std;const int maxn=100005;//最大数据数量int sum[maxn<<2];int lazy[maxn<<2];//记录延迟更新数组int N;//数据数量int Q;//操作次数void Push_Up(int root)//数据上浮{    sum[root]=sum[root<<1]+sum[root<<1|1];}void Push_Down(int root,int length)//数据下沉{    if(lazy[root]!=-1)//root对应区间需要被更新    {        lazy[root<<1]=lazy[root];        lazy[root<<1|1]=lazy[root];        sum[root<<1]=lazy[root]*(length-(length>>1));        sum[root<<1|1]=lazy[root]*(length>>1);        lazy[root]=-1;//标记root区间为已更新    }}void Build(int root,int left,int right){    lazy[root]=-1;//初始化为root区间已更新    sum[root]=1;    if(left==right)        return;    int mid=(left+right)>>1;    Build(root<<1,left,mid);    Build(root<<1|1,mid+1,right);    Push_Up(root);//数据上浮}void Update(int root,int left,int right,int find_left,int find_right,int num)//传入根节点,最大查找区间,待更改区间,待更改数值{    if(find_left<=left&&find_right>=right)//当前结点对应区间完全在待更新区间范围内    {        lazy[root]=num;        sum[root]=num*(right-left+1);        return;    }    Push_Down(root,right-left+1);//数据下沉一层    int mid=(left+right)>>1;    if(find_right<=mid)        Update(root<<1,left,mid,find_left,find_right,num);    else if(find_left>mid)        Update(root<<1|1,mid+1,right,find_left,find_right,num);    else    {        Update(root<<1,left,mid,find_left,mid,num);        Update(root<<1|1,mid+1,right,mid+1,find_right,num);    }    Push_Up(root);//更新后数据上浮}int main(){    int T;//T组数据    scanf("%d",&T);    for(int casen=1; casen<=T; casen++)    {        scanf("%d",&N);//N个数据        Build(1,1,N);//建树        scanf("%d",&Q);//操作次数        while(Q--)        {            int X,Y,Z;//含义如题            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",casen,sum[1]);    }    return 0;}
0 0
原创粉丝点击