题目链接:Click here~~
题意:
最经典的区间染色入门问题。
初始时区间[1,n]的颜色都是1,之后有若干操作,改变某段区间的颜色,输出最后区间[1,n]的颜色之和。
解题思路:
主要说如何做lazy标记。
就是更新时,不更新到最底层(那样太浪费时间)。
对每一个节点,用一个标记记录这段区间是否是同一段颜色。
更新时,若当前节点正好是需要更新的区间,只要直接对这个节点改变标记即可。
若不是,则说明当前节点的区间大于需要更新的区间,此时如果直接改变标记会将那些不属于更新区间的点也改变了颜色。
做法是:将当前节点的标记传给它的两个儿子,并把自己的标记清空,然后再继续更新它的儿子区间,这样就解决了上面的问题。
而查询时,如果碰到有标记的节点,则可以不用继续递归,直接返回这段区间的颜色之和。
如果没有标记,则需要访问它的两个儿子,才能知道这段区间的颜色之和。
#include <stdio.h>
#define L(x) (x<<1)
#define R(x) (x<<1|1)
#define MID(x,y) ((x+y)>>1)
typedef __int64 LL;
const int M = 100003;
struct Tnode
{
int l,r;
int color;
}T[M<<2];
void Build(int u,int l,int r)
{
T[u].l = l , T[u].r = r;
if(l == r-1)
{
T[u].color = 1;
return ;
}
int mid = MID(l,r);
Build(L(u),l,mid);
Build(R(u),mid,r);
T[u].color = 0;
}
void Updata(int u,int l,int r,int up)
{
if(T[u].color == up || T[u].l == l && T[u].r == r)
{
T[u].color = up;
return ;
}
if(T[u].color)
{
T[L(u)].color = T[u].color;
T[R(u)].color = T[u].color;
T[u].color = 0;
}
int mid = MID(T[u].l,T[u].r);
if(l >= mid)
Updata(R(u),l,r,up);
else
if(r <= mid)
Updata(L(u),l,r,up);
else
{
Updata(L(u),l,mid,up);
Updata(R(u),mid,r,up);
}
}
int Query(int u,int l,int r)
{
int mid = MID(T[u].l,T[u].r);
if(T[u].l == l && T[u].r == r)
if(T[u].color)
return T[u].color*(r-l);
else
return Query(L(u),l,mid) + Query(R(u),mid,r);
if(l >= mid)
return Query(R(u),l,r);
else
if(r <= mid)
return Query(L(u),l,r);
else
return Query(L(u),l,mid) + Query(R(u),mid,r);
}
int main()
{
//freopen("in.ads","r",stdin);
int n,z,Q,a,b,num;
int ncase = 0;
scanf("%d",&z);
while(z--)
{
scanf("%d%d",&n,&Q);
Build(1,1,n+1);
while(Q--)
{
scanf("%d%d%d",&a,&b,&num);
Updata(1,a,b+1,num);
}
printf("Case %d: The total value of the hook is %d.\n",++ncase,Query(1,1,n+1));
}
return 0;
}
分享到:
相关推荐
从简单入门到偏中等的几个题,线段树很灵活,主要懂了lazy操作,其他的自己yy吧。
hdu 1166线段树代码
hdu 1166线段树
【hdu5306】Gorgeous Sequence 线段树区间最值操作-附件资源
acm hdu as easy as a+b
hdu 1695 GCD(欧拉函数+容斥原理).docx
现在,给你两个正的小数A和B,你的任务是代表大明计算出A+B的值。 Input 本题目包含多组测试数据,请处理到文件结束。 每一组测试数据在一行里面包含两个长度不大于400的正小数A和B。 Output 请在一行里面...
线段树入门资料,有利于初学者学习,让他们详细了解线段树。
大量线段树题目 zoj 1610 线段覆盖 poj 2777 线段覆盖 poj 2528 需要离散化,建树不同,需要处理不同->注意这组数据 3 1 10 1 3 6 10 the ans is 3. hdu 1754 求区间最大值 hdu 1166 求区间和 hdu 1698 成段更新 ...
300+ AC 代码 。 大数 , 线段树 , 字符串 , dp.....
NULL 博文链接:https://128kj.iteye.com/blog/1738772
ACM题库,一些题目和答案,以及解题报告,传上来共享
本人准备2020年保研机试时刷的题目(虽然最后机试取消了,...来自某中流985,在HDU和vjudge平台上大概刷了400道。本文件地图(excel表格)包含了绝大部分我刷过的题目,笔记中具有思路、代码、总结和心得。 大佬勿入!
杭电OnlineJudge 200-2099的解题报告
hdu 3341(ac自动机+状态压缩) 题意:容易理解... 思路:首先一开始容易想到要用到dp,开设一个dp[41][41][41][41][501]的数组来解决,但是明显内存已经超出范围了,于是就想如何减少内存呢?只要知道A、T、C、G其中...
HDU的1250,主要是利用高精度加法,但是代码有点繁琐,效率不是很高
杭电ACMhdu1163
题面 【题目描述】 有nnn个营地,已知每个营地的人数,有四条命令: (1)Add(1) Add(1)Add iii jjj,iii和jjj为正整数,表示第iii个营地增加jjj个人(jjj不超过303030) (2)Sub(2)Sub(2)Sub iii jjj ,iii和jjj为正...
HDU1059的代码