Just a Hook HDU - 1698 (线段树区间)

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. 
InputThe 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. 
OutputFor 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 ,现在可改变任意段的价值,改为 1或2或3 ,问链子最后的价值

解 因为后面会覆盖前面 ,那么我们直接从后往前看 ,如果未被标记则标记他,并计算增加的价值

需要注意的是如果某一段的一部分被标记了  那么这一段我们视为-1,看代码中的解释

v[ ]代表某一段的状态   ,0   未标记   1, 完全被标记   -1   部分被标记

#include<stdio.h>
#include<string.h>
#include<map>
#include<vector>
#include<iostream>
#include<algorithm>
#include<queue>
#include<deque>
#include<math.h>
#define ll long long
#define ls rt<<1
#define rs rt<<1|1
#define maxn 120000
const int inf=0x3f3f3f3f;
int t,n,m,ans;
struct node
{
    int l,r,c;
}e[maxn];
int v[maxn<<2];
using namespace std;
void pushup(int rt)
{
    if(v[ls]==1&&v[rs]==1)//如果左儿子和右儿子都被标记 那么完全被标记,否则就是部分被标记
        v[rt]=1;
    else
        v[rt]=-1;
}
void update(int L,int R,int c,int l,int r,int rt)
{
    if(v[rt]==1) return;
    if(L<=l&&r<=R)//在范围内
    {
        if(v[rt]==0)
        {
            v[rt]=1;
            ans+=(r-l+1)*(c-1); //计算的是增加的部分
        return;//返回在if里面 ,因为如果是部分被标记 还不能返回 得往下找未被标记的部分
        }
    }
    int m=(l+r)>>1;
    if(L<=m&&v[ls]!=1) update(L,R,c,l,m,ls);
    if(R>m&&v[rs]!=1) update(L,R,c,m+1,r,rs);
    pushup(rt);//更新当前的状态
}
int main()
{
  scanf("%d",&t);
  for(int pp=1;pp<=t;pp++)
  {
      memset(v,0,sizeof(v));
     scanf("%d%d",&n,&m);
     ans=n;
     for(int i=1;i<=m;i++)
       scanf("%d%d%d",&e[i].l,&e[i].r,&e[i].c);
     for(int i=m;i>=1;i--)//从后往前
        update(e[i].l,e[i].r,e[i].c,1,n,1);
     printf("Case %d: The total value of the hook is %d.\n",pp,ans);
  }
}









猜你喜欢

转载自blog.csdn.net/dsaghjkye/article/details/81020472