zoukankan      html  css  js  c++  java
  • HDU-致命武器(线段树)

    月亮踩碎星光 你是一袋藏于银河的幻想

    原网站传送门
    以下为中文题面

    致命武器

    时间限制: 1 Sec 内存限制: 128 MB
    [命题人:admin] [ Edit] [ TestData]
    题目描述
    在DOTA游戏中,屠夫的肉钩是最可怕的武器,它是由一系列连续的相同长度的金属棒组成,金属棒编号为1到N。初始时金属棒为铜。 屠夫可以改变从X到Y的连续金属棒为铜、银或金。

    钩的总价值计算为N的金属棍棒的值的总和。更确切地说,每一种棒的价值计算公式如下:

    对于每个铜棒,值为1。

    对于每一个银棒,价值2。

    对于每一个金色的棍子,值为3。

    现在计算每次操作后的钩子的总价值。
    输入
    输入数据包括多组数据,第一行为组数,组数不超过10组。
    每一组数据中,第一行为数字N(1≤N≤100 000),第二行为操作数量Q(0≤Q≤100 000)
    接下来的Q行,每一行包括三个整数X,Y(1≤X≤Y≤N),Z(1≤Z≤3), 表示将从X到Y区间的金属棒变为Z,其中Z=1表示铜,Z=2表示银,Z=3表示金。
    输出
    每一组数据,打印出操作后的钩子的总价值。
    样例输入 Copy
    1
    10
    2
    1 5 2
    5 9 3
    样例输出 Copy
    Case 1: The total value of the hook is 24.

    思路: 线段树的区间修改,练练板子
    代码:

    #include<bits/stdc++.h>
    using namespace std;
    const int maxn=1e6+7;
    struct node{
        int l,r,sum;
        int lazy;
    }a[maxn*4];
    int n,m;
    void build(int u,int l,int r){
        a[u].l=l,a[u].r=r,a[u].lazy=1;
        if(l==r) return ;
        int mid=(l+r)>>1;
        build(u<<1,l,mid);build(u<<1|1,mid+1,r);
    }
    void update(int u,int l,int r,int z){
        if(a[u].lazy==z) return ;
        if(a[u].l==a[u].r){
            a[u].lazy=z;
            return ;
        }
        if(a[u].lazy!=-1){
            a[u<<1].lazy=a[u<<1|1].lazy=a[u].lazy;
            a[u].lazy=-1;
        }
        int mid=(a[u].l+a[u].r)>>1;
        if(r<=mid) update(u<<1,l,r,z);
        else if(l>=mid+1) update(u<<1|1,l,r,z);
        else update(u<<1,l,mid,z),update(u<<1|1,mid+1,r,z);
    }
    int query(int u,int l,int r){
        if(a[u].l>=l&&a[u].r<=r){
            if(a[u].lazy!=-1) return (a[u].r-a[u].l+1)*a[u].lazy;
            else return query(u<<1,l,r)+query(u<<1|1,l,r);
        }
        if(a[u].lazy!=-1){
            a[u<<1].lazy=a[u<<1|1].lazy=a[u].lazy;
            a[u].lazy=-1;
        }
        int mid=(a[u].l+a[u].r)>>1;
        int res=0;
        if(l<=mid) res+=query(u<<1,l,r);
        if(r>=mid+1) res+=query(u<<1|1,l,r);
        return res;
    }
    int main(){
        int t;scanf("%d",&t);
        for(int k=1;k<=t;k++){
            scanf("%d%d",&n,&m);
            build(1,1,n);
            while(m--){
                int x,y,z;
                scanf("%d%d%d",&x,&y,&z);
                update(1,x,y,z);
            }
            printf("Case %d: The total value of the hook is %d.
    ",k,query(1,1,n));
        }
        return 0;
    }
    
    
  • 相关阅读:
    jqueryautocomplete
    了解CSS的查找匹配原理 让CSS更简洁、高效
    html5网页编码
    刚开始学习 mvc碰到的郁闷问题
    datatable 批量插入方法 求解?
    28个经过重新设计的著名博客案例(1120)
    递归调用中的return
    C++新建一个模板
    C++ 中用 sizeof 判断数组长度
    为什么MySQL选择REPEATABLE READ作为默认隔离级别?
  • 原文地址:https://www.cnblogs.com/OvOq/p/14853186.html
Copyright © 2011-2022 走看看