首页 > 其他分享 >HDU 1698(线段树 区间更新)

HDU 1698(线段树 区间更新)

时间:2023-08-15 17:31:33浏览次数:45  
标签:rt HDU sticks 线段 value hook each include 1698


Just a Hook



Time Limit: 4000/2000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)


Total Submission(s): 23481    Accepted Submission(s): 11758





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.




HDU 1698(线段树 区间更新)_Java



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.


 


#include <iostream>
#include <stdio.h>
#include <string.h>
#include <cmath>
#include <algorithm>
#include <map>
#include <queue>
using namespace std;
const int maxn=100000+10;
const int inf=(1<<30);
struct Node
{
    int l,r,sum,mark;  //sum 为区间的和 mark:被标记过没 1 标记过
    int ic;  //上次更新的值
    int mid()
    {
        return (l+r)/2;
    }
}tree[maxn*4];

void Buildtree(int rt,int l,int r)
{
    tree[rt].l=l;
    tree[rt].r=r;
    tree[rt].ic=0;
    tree[rt].mark=0;
    if(l!=r)
    {
        Buildtree(2*rt,l,(l+r)/2);
        Buildtree(2*rt+1,(l+r)/2+1,r);
        tree[rt].sum=tree[2*rt].sum+tree[rt*2+1].sum; //回溯求和
    }
    else
        tree[rt].sum=1;
}
void Update(int rt,int l,int r,int val)
{
    if(tree[rt].l==l&&tree[rt].r==r)  //找到区间时的结果 标记为1
    {
        tree[rt].sum=(tree[rt].r-tree[rt].l+1)*val;
        tree[rt].ic=val;
        tree[rt].mark=1;
        return;
    }
    if(tree[rt].mark)  //当被标记时向下两个儿子也要更新父节点所更新的值

    {
        tree[2*rt].sum=(tree[2*rt].r-tree[2*rt].l+1)*tree[rt].ic;
        tree[2*rt+1].sum=(tree[2*rt+1].r-tree[2*rt+1].l+1)*tree[rt].ic;
        tree[2*rt].mark=tree[2*rt+1].mark=1;  //标记为1
        tree[2*rt].ic=tree[2*rt+1].ic=tree[rt].ic;
        tree[rt].mark=tree[rt].ic=0;  //标记为0
    }
    if(r<=tree[rt].mid())
        Update(2*rt,l,r,val);
    else if(l>tree[rt].mid())
        Update(2*rt+1,l,r,val);
    else
    {
        Update(2*rt,l,tree[rt].mid(),val);
        Update(2*rt+1,tree[rt].mid()+1,r,val);
    }
    tree[rt].sum=tree[2*rt].sum+tree[rt*2+1].sum;
}

int main()
{
    int t,cnt=1;
    scanf("%d",&t);
    while(t--)
    {
        int n;
        scanf("%d",&n);
        Buildtree(1,1,n);
        int m;
        scanf("%d",&m);
        while(m--)
        {
            int l,r,val;
            scanf("%d%d%d",&l,&r,&val);
            Update(1,l,r,val);
        }
        printf("Case %d: The total value of the hook is %d.\n",cnt++,tree[1].sum);
    }
    return 0;
}



标签:rt,HDU,sticks,线段,value,hook,each,include,1698
From: https://blog.51cto.com/u_3936220/7091434

相关文章

  • HDU 3829 Cat VS Dog 猫和狗(二分图)结题报告
    听学长说这道题很ex,但是思路想到的话还是挺简单的。可能是受上一道题(放置机器人)的启发,也是找互相冲突的点连线。但是并不是完全一样(废话)放置机器人那道题是找到冲突点连线后直接求最大匹配即可。这道题稍微把思路变换一下,求出最大完美匹配数\(n\)后,说明有\(n*2\)个人的喜好......
  • [蓝桥杯 2021 省 B] 双向排序 (线段树)
    调了整整5个小时,结果发现自己建树的方式有误,气死我了气死我了,比较好的一道线段树(虽然我不会-----#include<bits/stdc++.h>usingnamespacestd;constintN=1e6+10;intn,m,res,point;vector<int>v[2];//用于存储结果的数组,下标0表示sum为0,下标1表示sum为1structno......
  • HDU7326 string magic(Easy Version)
    HDU7326stringmagic(EasyVersion)tag:回文自动机题目链接题意:多组样例,每组输入一字符串(长度1e5以内),输出满足下列条件的子串个数:该串由两个完全相同的回文串拼接而成做法:字符串的题目一般都比较板,洛谷的P4287可以说是这道题目的原题,我们先看看原题是怎么做的P4287双......
  • hdu7365 0 vs 1
    0vs1首先如果两端不同肯定只能直接选。两端都选不了直接失败。不妨设现在是zero在选,从左边来010101交替,如果先出现了一个00比如01010100.....10那么我们就能从这边选,因为one只能跟着我们选这边,最后会出现两边都是0的情况。从右边来同理。假如是0101010交替,那么肯定是平......
  • 线段相交Ⅲ
    描述 线段相交有两种情形:一种是“规范相交”,另一种是“非规范相交”。规范相交是指两条线段恰有唯一一个不是端点的公共点。即如果一条线段的端点在另一条线段上则不视为相交。如果两条线段有部分重合,也不视为相交。而非规范相交则把以上两种情况都视为相交。如下图所示:规范......
  • 「学习笔记」线段树优化建图
    在建图连边的过程中,我们时常会碰到这种题目,一个点向一段连续的区间中的点连边或者一个连续的区间向一个点连边,如果我们真的一条一条连过去,那一旦点的数量多了复杂度就爆炸了,这里就需要用线段树的区间性质来优化我们的建图了。那棵线段树大概长这个样子。到时候加边的时候是这个......
  • 线段树
    线段树线段树是一种二叉树形数据结构,用于解决区间查询和区间修改问题。它将一个数组划分为若干个连续的区间,每个区间对应线段树的一个节点。通过递归地构建线段树,我们可以在O(logn)的时间复杂度内完成区间查询和区间修改操作。原理线段树的构建过程如下:将原数组划分为n个子......
  • 在不完全重合的情况下,判断线经过另一线段的方法
    importlogginglogging.basicConfig(level=logging.INFO,format='%(asctime)s-%(filename)s[line:%(lineno)d]-%(levelname)s:%(message)s',datefmt='%Y-%m-%d%H:%M:%S')importnumpyasnpfromshapely.......
  • 【数据结构】线段树
    例题1:给定一个正整数数列,每一个数都在添加操作:向序列后添加一个数,序列长度变成;询问操作:询问这个序列中最后程序运行的最开始,整数序列为空。一共要对整数序列进行次操作。写一个程序,读入操作的序列,并输出询问操作的答案。数据范围这道题看第一眼:暴力,再看一眼:爆炸(bushiTLE。......
  • HDU 多校 Round #6 题解
    HDU多校Round#6题解\(\text{ByDaiRuiChen007}\)A.CountProblemLink题目大意求有多少个长度为\(n\),字符集大小为\(m\)的字符串有长度为\(n-k\)的周期。数据范围:\(n,m,k\le10^{18}\)。思路分析\(k=n\)时答案为\(m^n\),否则转为有长度为\(k\)的Border,答案......