题目链接: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. javascript中对象字面量的理解

    javascript中对象字面量与数组字面量 第一部分 我们知道JavaScript中的数据类型有基本数据类型和引用类型,其中Object类型就是非常常用的类型.那么如果创建一个Object类型的实例 ...

  2. 手写控件,frame,center和bounds属性

    一.手写控件 1.手写控件的步骤 (1)使用相应的控件类创建控件对象 (2)设置该控件的各种属性 (3)添加控件到视图中 (4)如果是button等控件,还需考虑控件的单击事件等 (5)注意:View ...

  3. 最短路径(Floyd)算法

    #include <stdio.h>#include <stdlib.h>/* Floyd算法 */#define VNUM 5#define MV 65536int P[VN ...

  4. css012 css布局简介

    css012  css布局简介 一.    网页布局的类型 网页布局的类型 1.固定宽度 2.流式 3.相应式web设计 二.    如何进行css布局 1.强大的<div>标签 网页的h ...

  5. 自然语言18.2_NLTK命名实体识别

    QQ:231469242 欢迎nltk爱好者交流 http://blog.csdn.net/u010718606/article/details/50148261 NLTK中对于很多自然语言处理应用有 ...

  6. ubuntu下怎么解决python "Non-ASCII character"错误

    解决方法:源代码文件第一行添加:#coding:utf-8 参考:  http://jingyan.baidu.com/album/219f4bf7d04887de442d3899.html?pici ...

  7. 关于软件工程结对编程作业 PairProject : Elevator Scheduler(电梯调度算法的实现与测试)的总结

    1)结对编程队友 1106xxxx 张扬 1106xxxx 杨军 其中,此项目的编程实现主要由前者完成. 2)关于结对编程 结对编程的优点: 最直接的一点:在结对编程中,由于有另一个人在你身边和你配合 ...

  8. openstack虚拟机启动过程

    核心项目3个 1.控制台 服务名:Dashboard 项目名:Horizon 功能:web方式管理云平台,建云主机,分配网络,配安全组,加云盘 2.计算 服务名:计算 项目名:Nova 功能:负责响应 ...

  9. 设计模式学习——观察者模式(Observer Pattern)

    0. 前言 观察者模式在许多地方都能够用到,特别是作为MVC模式的一部分,在MVC中,模型(M):存放数据,视图(V):显示数据.当模型中的数据发生改变时,视图会得到通知,这是典型的观察者模式. 1. ...

  10. top命令详解(转,详细)

    来源:脚本之家(http://www.jb51.net/article/40807.htm) 本文通过一个运行中的WEB服务器的top监控截图,讲述top视图中的各种数据的含义,还包括视图中各进程(任 ...