`
Simone_chou
  • 浏览: 192508 次
  • 性别: Icon_minigender_2
  • 来自: 广州
社区版块
存档分类
最新评论

Sliding Window(线段树)

 
阅读更多
Sliding Window
Time Limit: 12000MS   Memory Limit: 65536K
Total Submissions: 32563   Accepted: 9681
Case Time Limit: 5000MS

Description

An array of size n ≤ 106 is given to you. There is a sliding window of size k which is moving from the very left of the array to the very right. You can only see the k numbers in the window. Each time the sliding window moves rightwards by one position. Following is an example: 
The array is [1 3 -1 -3 5 3 6 7], and k is 3. Window position Minimum value Maximum value
[1  3  -1] -3  5  3  6  7  -1 3
 1 [3  -1  -3] 5  3  6  7  -3 3
 1  3 [-1  -3  5] 3  6  7  -3 5
 1  3  -1 [-3  5  3] 6  7  -3 5
 1  3  -1  -3 [5  3  6] 7  3 6
 1  3  -1  -3  5 [3  6  7] 3 7

Your task is to determine the maximum and minimum values in the sliding window at each position. 

Input

The input consists of two lines. The first line contains two integers n and k which are the lengths of the array and the sliding window. There are n integers in the second line. 

Output

There are two lines in the output. The first line gives the minimum values in the window at each position, from left to right, respectively. The second line gives the maximum values. 

Sample Input

8 3
1 3 -1 -3 5 3 6 7

Sample Output

-1 -3 -3 -3 3 3
3 3 5 5 6 7

 

    题意:

    有N(1到10^6)个数,每K(1到N)个数一组。求出每组的最小值和最大值,最小值和最大值分别一行输出。

 

    思路:

    线段树基础题。线段树维护最大值最小值。

 

    AC:

#include<stdio.h>
#define MAX 1000005
typedef struct
{
	int l;
	int r;
	int min;
	int max;
}node;
node no[MAX*5];
int num[MAX];
int fma,fmi;

void build(int from,int to,int i)
{
	int mid=(from+to)/2;
	no[i].l=from;
	no[i].r=to;
	if(from==to)
	{
		no[i].max=num[from];
		no[i].min=num[from];
		return;
	}
	build(from,mid,2*i);
	build(mid+1,to,2*i+1);
	no[i].max=(no[2*i].max>no[2*i+1].max?no[2*i].max:no[2*i+1].max);
	no[i].min=(no[2*i].min<no[2*i+1].min?no[2*i].min:no[i*2+1].min);
}

void findmax(int from,int to,int i)
{
	int mid=(no[i].l+no[i].r)/2;
	if(from==no[i].l&&to==no[i].r)
	{
		fma=(fma>no[i].max?fma:no[i].max);
		return;
	}
	if(from>=mid+1) findmax(from,to,2*i+1);
	if(to<=mid)		findmax(from,to,2*i);
	if(from<=mid&&to>=mid+1)
	{
		findmax(from,mid,2*i);
		findmax(mid+1,to,2*i+1);
	}
}

void findmin(int from,int to,int i)
{
	int mid=(no[i].l+no[i].r)/2;
	if(from==no[i].l&&to==no[i].r)
	{
		fmi=(fmi>no[i].min?no[i].min:fmi);
		return;
	}
	if(from>=mid+1) findmin(from,to,2*i+1);
	if(to<=mid)	findmin(from,to,2*i);
	if(from<=mid&&to>=mid+1)
	{
		findmin(from,mid,2*i);
		findmin(mid+1,to,2*i+1);
	}
}

int main()
{
	int n,m;
	scanf("%d%d",&n,&m);
		for(int i=1;i<=n;i++)
			scanf("%d",&num[i]);
		build(1,n,1);
		for(int i=1;i<=n-m+1;i++)
		{
			fmi=num[i];
//WA了N遍,就是因为赋值这里
//一开始赋值fmi=MAX;
//因为fmin是int型的,存MAX不够存
			findmin(i,i+m-1,1);
			printf("%d",fmi);
			i==n-m+1?printf("\n"):printf(" ");
		}
		for(int i=1;i<=n-m+1;i++)
		{
			fma=num[i];
//同理,这里也不可以赋值为fma=-MAX
			findmax(i,i+m-1,1);
			printf("%d",fma);
			i==n-m+1?printf("\n"):printf(" ");
		}
	return 0;
}

 

    总结:

    1.细节的错误现在遇到得比较多,都是不容易发现的错误;

    2.不是多输入和输出格式的错误,赋值的时候要注意要在数据范围内赋值。

 

 

 

分享到:
评论
2 楼 Simone_chou 2013-09-10  
yomean 写道
http://www.notonlysuccess.com/index.php/segment-tree-complete/
在这个网址里面,把区间合并还有扫描线的题做了。
别的类似的重复的题不要做了。

好!
1 楼 yomean 2013-09-09  
http://www.notonlysuccess.com/index.php/segment-tree-complete/
在这个网址里面,把区间合并还有扫描线的题做了。
别的类似的重复的题不要做了。

相关推荐

    Go 零基础2000题 从入门到精通

    说明 ⽬录 第⼀章 序章 关于 LeetCode ...线段树 Segment Tree 并查集 UnionFind 第四章 Leetcode 题解 1. Two Sum 2. Add Two Numbers 3. Longest Substring Without Repeating Characters 4. ......

    ACM中的RMQ和LCA问题

    总的来说,RMQ和LCA是ACM中重要且实用的数据结构问题,它们涉及到动态规划、线段树、Sparse Table、并查集等多种数据结构和算法,对于提高解决问题的能力和效率具有很高的价值。学习和掌握这些知识对于参赛者来说至...

    蓄水池算法leetcode-leetcode-cn.go:leetcode-cn.go

    蓄水池算法 leetcode ...线段树 12 Ordered Map 10 队列 10 几何 9 极小化极大 8 树状数组 6 Line Sweep 6 Random 6 拓扑排序 6 二叉搜索树 5 脑筋急转弯 5 记忆化 3 Rejection Sampling 2 蓄水池抽样 2

    leetcode双人赛-bestlyg-leetcode:个人LeetCode题解

    leetcode双人赛 bestlyg-leetcode 介绍 个人 LeetCode 题解 待完成题 顺序索引 1-200 201-400 401-600 601-800 801-1000 1001-1200 ...Sliding Window ...线段树 记忆化 递归 队列 难度索引 简单 中等 困难

    蓄水池算法leetcode-myLeetCodeSummary:myLeetCode总结

    线段树 二叉搜索树 递归 脑筋急转弯 记忆化 队列 极小化极大 蓄水池抽样 几何 Map 数组 哈希表 链表 数学 双指针 字符串 二分查找 分治算法 动态规划 回溯算法 Random Rejection Sampling Sliding Window Ordered ...

    ACM算法模板和pku代码

    Sliding Window 数据结构 线段树 Cows 线段染色 排队问题 第K大的数 离散化+线段树 灯光投影 网络赛取连续子序列问题 线段树+树状数组+并查集,转化为排队问题 离散化 离散化矩形切割,矩形覆盖面积统计 ...

    蓄水池算法leetcode-LeetCode:力码

    滑动窗口(SlidingWindow) 字典树(Trie) 递归(Recursion) OrderedMap(OrderedMap) 线段树(SegmentTree) 队列(Queue) 极小化极大(Minimax) 树状数组(BinaryIndexedTree) Random(Random) 拓扑排序...

    LeetCode刷题手册.docx

    第三章介绍了模板,包括线段树(Segment Tree)和并查集(UnionFind),这些模板对于解决特定类型的问题非常有用。 第四章是手册的核心,详细解答了LeetCode上的一系列经典题目。这些题目涵盖了从基础到高级的各种...

    RMQ与LCA ACM必备

    线段树(Segment Tree)也是一种解决RMQ问题的有效工具,可以实现O(logn)的查询和更新操作。此外,还可以通过滚动数组(Sliding Window)优化特定情况下的空间占用,如POJ 2823问题。 **LCA(Least Common ...

Global site tag (gtag.js) - Google Analytics