题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=4902

解题报告:输入一个序列,然后有q次操作,操作有两种,第一种是把区间 (l,r) 变成x,第二种是把区间 (l,r) 中大于x的数跟 x 做gcd操作。

线段树区间更新的题目,每个节点保存一个最大和最小值,当该节点的最大值和最小值相等的时候表示这个区间所有的数字都是相同的,可以直接对这个区间进行1或2操作,

进行1操作时,当还没有到达要操作的区间但已经出现了节点的最大值跟最小值相等的情况时,说明这个区间的值都是相同的,但现在我只要在这个区间的一部分进行1操作,所以

我要先把这个节点的最大的最小值往下压,直到找到了要操作的区间。

进行2操作时,如果该区间的最大值都小于x,则可以直接退出,如果最大值大于x,则表示这个区间可以进行gcd操作,然后继续往下,直到找到最大值跟最小值相等的区间才开始

进行gcd操作,进行gcd操作之后不要忘了更新父节点的最大最小值。

 #include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
using namespace std;
#define maxn 100005
struct node
{
int Max,Min,l,r;
}tree[*maxn];
void build(int p)
{
if(tree[p].l == tree[p].r) return ;
int mid = (tree[p].l + tree[p].r) / ;
tree[*p].Max = tree[*p+].Max = -;
tree[*p].Min = tree[*p+].Min = 0x7fffffff;
tree[*p].l = tree[p].l;
tree[*p].r = mid;
tree[*p+].l = mid + ;
tree[*p+].r = tree[p].r;
build(*p);
build(*p+);
}
void push(int p,int l,int d)
{
tree[p].Max = max(tree[p].Max,d);
tree[p].Min = min(tree[p].Min,d);
if(tree[p].l == tree[p].r) return ;
int mid = (tree[p].l + tree[p].r) / ;
if(l <= mid) push(*p,l,d);
else push(*p+,l,d);
}
int gcd(int a,int b)
{
return b == ? a : gcd(b,a%b);
}
void oper1(int p,int l,int r,int x)
{
if(tree[p].l == l && tree[p].r == r)
{
tree[p].Max = tree[p].Min = x;
return ;
}
int mid = (tree[p].l + tree[p].r) / ;
if(tree[p].Max == tree[p].Min)
{
oper1(*p+,mid+,tree[p].r,tree[p].Max); //先把当前区间的值往下压
oper1(*p,tree[p].l,mid,tree[p].Max);
}
tree[p].Max = max(tree[p].Max,x);
tree[p].Min = min(tree[p].Min,x);
if(r <= mid)
oper1(*p,l,r,x);
else if(l <= mid && r > mid)
{
oper1(*p,l,mid,x);
oper1(*p+,mid+,r,x);
}
else oper1(*p+,l,r,x);
}
void oper2(int p,int l,int r,int x)
{
int mid = (tree[p].l + tree[p].r) / ;
if(tree[p].l == l && tree[p].r == r)
{
if(tree[p].Max < x) return ; //最大的都不可以进行gcd操作,直接退出
if(tree[p].Max == tree[p].Min) //找到了值都相同的区间,可以直接进行gcd操作
{
if(tree[p].Max > x) tree[p].Max = tree[p].Min = gcd(tree[p].Max,x);
return ;
}
else if(tree[p].Max > x)
{
oper2(*p,l,mid,x);
oper2(*p+,mid+,r,x);
}
return ;
}
if(tree[p].Max == tree[p].Min) //还没找到操作的区间之前碰到了这个,则也要通过1操作,把这个节点的值往下压
{
oper1(*p,tree[p].l,mid,tree[p].Max);
oper1(*p+,mid+,tree[p].r,tree[p].Max);
}
if(r <= mid)
oper2(*p,l,r,x);
else if(l <= mid && r > mid)
{
oper2(*p,l,mid,x);
oper2(*p+,mid+,r,x);
}
else oper2(*p+,l,r,x);
if(tree[p].l != tree[p].r) //记得更新父节点的最大最小值
{
tree[p].Max = max(tree[*p].Max,tree[*p+].Max);
tree[p].Min = min(tree[*p].Min,tree[*p+].Min);
}
}
int query(int p,int l)
{
int mid = (tree[p].l + tree[p].r) / ;
if(tree[p].Max == tree[p].Min)
return tree[p].Max;
if(l <= mid) return query(*p,l);
else return query(*p+,l);
} int main()
{
int T,n;
scanf("%d",&T);
while(T--)
{
scanf("%d",&n);
tree[].Max = -;
tree[].Min = 0x7fffffff;
tree[].l = ;
tree[].r = n;
build();
int d;
for(int i = ;i <= n;++i)
{
scanf("%d",&d);
push(,i,d);
}
int q,t,l,r,x;
scanf("%d",&q);
while(q--)
{
scanf("%d%d%d%d",&t,&l,&r,&x);
if(t == ) oper1(,l,r,x);
else oper2(,l,r,x);
}
for(int i = ;i <= n;++i) //输出有点不同,PE了好几次,最后也是有空格的
printf("%d ",query(,i));
puts("");
}
return ;
}

HDU 4902 Nice boat 2014杭电多校训练赛第四场F题(线段树区间更新)的更多相关文章

  1. HDU 4941 Magical Forest(map映射+二分查找)杭电多校训练赛第七场1007

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=4941 解题报告:给你一个n*m的矩阵,矩阵的一些方格中有水果,每个水果有一个能量值,现在有三种操作,第 ...

  2. HDU 4864 Task (贪心+STL多集(二分)+邻接表存储)(杭电多校训练赛第一场1004)

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=4864 解题报告:有n台机器用来完成m个任务,每个任务有一个难度值和一个需要完成的时间,每台机器有一个可 ...

  3. 线段树 + 区间更新: HDU 4893 Wow! Such Sequence!

    Wow! Such Sequence! Time Limit: 10000/5000 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Oth ...

  4. HDU 5023 A Corrupt Mayor's Performance Art(线段树区间更新)

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=5023 解题报告:一面墙长度为n,有N个单元,每个单元编号从1到n,墙的初始的颜色是2,一共有30种颜色 ...

  5. hdu 4031 attack 线段树区间更新

    Attack Time Limit: 5000/3000 MS (Java/Others)    Memory Limit: 65768/65768 K (Java/Others)Total Subm ...

  6. hdu 3966(树链剖分+线段树区间更新)

    传送门:Problem 3966 https://www.cnblogs.com/violet-acmer/p/9711441.html 学习资料: [1]线段树区间更新:https://blog.c ...

  7. HDU.1556 Color the ball (线段树 区间更新 单点查询)

    HDU.1556 Color the ball (线段树 区间更新 单点查询) 题意分析 注意一下pushdown 和 pushup 模板类的题还真不能自己套啊,手写一遍才行 代码总览 #includ ...

  8. 线段树 + 区间更新 ----- HDU 4902 : Nice boat

    Nice boat Time Limit: 30000/15000 MS (Java/Others)    Memory Limit: 131072/131072 K (Java/Others)Tot ...

  9. 【HDU】4092 Nice boat(多校第四场1006) ——线段树 懒惰标记

    Nice boat Time Limit: 30000/15000 MS (Java/Others)    Memory Limit: 131072/131072 K (Java/Others) To ...

随机推荐

  1. linux Basis --- tar command

    -c: compress archives -x:decompress archives -t:check archives -z:whether it has the attribute of gz ...

  2. struts2文件目录结构

    apps 文件夹包含了多个 example 示例应用的压缩包. docs 文件夹包含了 struts 官方的帮助文档. lib 文件夹包含了 struts 提供的类库 jar 包. src 文件夹包含 ...

  3. HTML 速查列表

    HTML 基本文档 <!DOCTYPE html> <html> <head> <title>文档标题</title> </head& ...

  4. ASP.NET 递归将分类绑定到 TreeView

    CREATE TABLE [dbo].[sysMenuTree]([NoteId] [decimal](18, 0) NOT NULL,[ParentId] [decimal](18, 0) NULL ...

  5. BIOS设置第一启动项

    在电脑的Bois中怎样去设置第一启动项.. 对于很多新手朋友来说,BIOS满屏英文,生涩难懂,话说我原来也很排斥BIOS,界面太丑,光看界面就没什么兴趣,更谈不上深入研究,大多数人在电脑城装机的时候都 ...

  6. PHP----遇到的Session问题

    使用SESSION,当跨页面使用时,会提示错误Cannot modify header information - headers already sent by..., 背景:使用session_s ...

  7. Mastering C# structs

    http://www.developerfusion.com/article/84519/mastering-structs-in-c/

  8. ecshop 活动-》红包

    按商品发放:可以给指定某个商品发红包(购买付款,卖家发货后,会自动给买家发送红包:不是买家在付款的时候就自动可以减少红包金额) 按订单金额发放:订单满xx后(卖家发货后,会自动给买家发放红包)

  9. jQuery 元素的选中, 置顶、上移、下移、置底、删除

    如截图: <ul> <li class="li01" onclick="C_columnSetTop(this)"><i>& ...

  10. MVC缓存OutPutCache学习笔记 (一) 参数配置

    OutPutCache 参数详解 Duration : 缓存时间,以秒为单位,这个除非你的Location=None,可以不添加此属性,其余时候都是必须的. Location : 缓存放置的位置; 该 ...