区间最小值(2) (线段树 更新区间)2015年 JXNU_ACS 算法组暑假第一次周赛

区间最小值(2)

Time Limit : 3000/1000ms (Java/Other)   Memory Limit : 65535/32768K (Java/Other)
Total Submission(s) : 26   Accepted Submission(s) : 9

Font: Times New Roman | Verdana | Georgia

Font Size: ← →

Problem Description

给定一个数字序列以及一些操作,查询任意给定区间内数字的最小值。

Input

输入包含多组测试数据,最多5组。

输入包含多组测试用例,每组测试用例的开头为一个整数n(1<=n<=100000),代表数字序列的长度。

接下去一行给出n个数字,代表数字序列。数字在int范围内。

下一行为一个整数t(1<=t<=10000),代表操作的次数。

最后t行,每行给出一个操作,1 l r代表查询区间 [l,r]的最小值,0 l r c代表将区间[l r]的值全部替换为c (1<=l<=r<=n),c在整形范围内。

Output

对于每个查询,输出区间[l,r]内的最小值。

Sample Input

5
1 2 3 4 5
7
1 1 5
0 1 3 6
1 1 4
1 2 3
0 2 2 0
1 1 2
1 3 5

Sample Output

1
4
6
0
4

Author

吴迎



Statistic | Submit | Back

迟到了五分钟才做了。。感觉做的是对的。虽然没能提交上。

找了一天了。。TM我终于找到怎么做了。。上午的时候其实就知道怎么更新区间了,只不过一个地方写错了

导致结果不对 就放弃了。。

今天下午尝试了那么多。。o(︶︿︶)o 唉 刚刚发现上午写的是对的。

#include <stdio.h>
#include <string.h>
#include <algorithm>
using namespace std;
int num[100005];
struct node
{
	int left,right,val;
}c[100005*4];
void build_tree(int l,int r,int root)
{
	c[root].left=l;
	c[root].right=r;
	if(l==r)
	{
		c[root].val=num[l];
		return ;
	}
	int mid=(l+r)/2;
	build_tree(l,mid,root*2);
	build_tree(mid+1,r,root*2+1);
	c[root].val=min(c[root*2].val,c[root*2+1].val);
}
void find_tree(int l,int r,int &min1,int root)
{
	if(c[root].left==l&&c[root].right==r)
	{
		min1=c[root].val;
		return ;
	}
	int mid=(c[root].left+c[root].right)/2;
	if(mid<l)
	find_tree(l,r,min1,root*2+1);
	else if(mid>=r)
	find_tree(l,r,min1,root*2);
	else
	{
		int min2;
		find_tree(l,mid,min1,root*2);
		find_tree(mid+1,r,min2,root*2+1);
		min1=min(min1,min2);
	}

}
void update_tree(int l,int r,int x,int root)
{
	if(c[root].left==c[root].right)
	{
		c[root].val=x;
		return ;
	}
	int mid=(c[root].left+c[root].right)/2;
	if(mid<l)
	update_tree(l,r,x,root*2+1);
	else if(mid>=r)
	update_tree(l,r,x,root*2);
	else
	{
		update_tree(l,mid,x,root*2);
		update_tree(mid+1,r,x,root*2+1);
		c[root].val=min(c[root*2].val,c[root*2+1].val);
	}
}
int main()
{
	int n,k;
	while(scanf("%d",&n)!=EOF)
	{
		for(int i=1;i<=n;i++)
		scanf("%d",&num[i]);
		build_tree(1,n,1);
		scanf("%d",&k);
		while(k--)
		{
			int a,b,min1,flag;
			scanf("%d",&flag);
			if(flag)
			{
				scanf("%d %d",&a,&b);
				find_tree(a,b,min1,1);
				printf("%d\n",min1);
			}
			else
			{
				int x;
				scanf("%d %d %d",&a,&b,&x);
				update_tree(a,b,x,1);
				//for(int i=1;i<=9;i++)
				//printf("[%d %d] %d\n",c[i].left,c[i].right,c[i].val);//自己测试的。。
			}
		}
	}
	return 0;
}

版权声明:本文为博主原创文章,未经博主允许不得转载。

时间: 2024-10-13 08:29:26

区间最小值(2) (线段树 更新区间)2015年 JXNU_ACS 算法组暑假第一次周赛的相关文章

区间最小值 线段树 (2015年 JXNU_ACS 算法组暑假第一次周赛)

区间最小值 Time Limit : 3000/1000ms (Java/Other)   Memory Limit : 65535/32768K (Java/Other) Total Submission(s) : 12   Accepted Submission(s) : 5 Font: Times New Roman | Verdana | Georgia Font Size: ← → Problem Description 给定一个数字序列,查询随意给定区间内数字的最小值. Input

分水果 DP(2015年 JXNU_ACS 算法组暑假第一次周赛)

分水果 Time Limit : 3000/1000ms (Java/Other)   Memory Limit : 65535/32768K (Java/Other) Total Submission(s) : 16   Accepted Submission(s) : 7 Font: Times New Roman | Verdana | Georgia Font Size: ← → Problem Description 给定n个水果,每个水果都有一个重量,分成两堆,怎么分才使得分得的重量

递减打印最大的N位数到1 (2015年 JXNU_ACS 算法组暑假第一次周赛)

递减打印最大的N位数到1 Time Limit : 3000/1000ms (Java/Other)   Memory Limit : 65535/32768K (Java/Other) Total Submission(s) : 21   Accepted Submission(s) : 4 Font: Times New Roman | Verdana | Georgia Font Size: ← → Problem Description 给定一个数字N,M,递减打印最大的N位数到1的前M

一位数 (2015年 JXNU_ACS 算法组暑假第一次周赛)

一位数 Time Limit : 3000/1000ms (Java/Other)   Memory Limit : 65535/32768K (Java/Other) Total Submission(s) : 17   Accepted Submission(s) : 9 Font: Times New Roman | Verdana | Georgia Font Size: ← → Problem Description 对于一个正整数,递归使用如下的规则总是可以使它成为一位数,这个规则是

HDU 1556 Color the ball 线段树更新区间查点

点击打开链接 Color the ball Time Limit: 9000/3000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) Total Submission(s): 9120    Accepted Submission(s): 4665 Problem Description N个气球排成一排,从左到右依次编号为1,2,3....N.每次给定2个整数a b(a <= b),lele便为骑上他的"小飞鸽

2015 年 JXNU_ACS 算法组寒假第二次周赛

2015 年 JXNU_ACS 算法组寒假第二次周赛 比赛链接:http://acm.hdu.edu.cn/diy/contest_show.php?cid=26246 Start Time : 2015-02-01 13:00:00 End Time : 2015-02-01 17:30:00 终榜:http://acm.hdu.edu.cn/diy/contest_ranklist.php?cid=26246&page=1 这次比赛考查的知识都很基础,甚至还有几道就是C语言基础(比如1006

nyoj1185 最大最小值 (线段树求区间最大值和最小值)

对于不懂线段树的,先看为这篇文章理解下.点击打开链接 这道题普通方法 ,TLE. 最大最小值 时间限制:1000 ms  |  内存限制:65535 KB 难度:2 描述 给出N个整数,执行M次询问. 对于每次询问,首先输入三个整数C.L.R: 如果C等于1,输出第L个数到第R个数之间的最小值: 如果C等于2,输出第L个数到第R个数之间的最大值: 如果C等于3,输出第L个数到第R个数之间的最小值与最大值的和. (包括第L个数和第R个数). 输入 首先输入一个整数T(T≤100),表示有T组数据.

CodeForces 52C Circular RMQ(区间循环线段树,区间更新,区间求和)

转载请注明出处:http://blog.csdn.net/u012860063 题目链接:http://codeforces.com/problemset/problem/52/C You are given circular array a0,?a1,?...,?an?-?1. There are two types of operations with it: inc(lf,?rg,?v) - this operation increases each element on the segm

HDU 1556 Color the ball(线段树:区间更新)

http://acm.hdu.edu.cn/showproblem.php?pid=1556 题意: N个气球,每次[a,b]之间的气球涂一次色,统计每个气球涂色的次数. 思路: 这道题目用树状数组和线段树都可以,拿这道题来入门一下线段树的区间更新. 1 #include<iostream> 2 #include<cstring> 3 #include<algorithm> 4 using namespace std; 5 6 const int maxn = 1000