HDU ACM 4417 Super Mario 离线线段树

分析:离线线段树,把所有询问离线读入,然后按H从小到大排序。对于所有结点也按从小到大排序,然后根据查询的H,将比H小的点加入到线段树,最后就是一个区间求和。这题貌似也可以用划分树,树状数组等方法做。

#include<iostream>
#include<algorithm>
using namespace std;

#define N 100005

struct Tree
{
	int left,right,cnt;
} TREE[N<<2];

struct Query
{
	int l,r,h,id;

	bool operator<(const Query& q)const
	{
		return h<q.h;
	}
} query[N];

struct Node
{
	int pos,val;

	bool operator<(const Node& n)const
	{
		return val<n.val;
	}
} node[N];

void Build(int root,int l,int r)
{
	int m;

	TREE[root].cnt=0;
	TREE[root].left=l;
	TREE[root].right=r;

	if(l==r) return ;
	m=(l+r)>>1;
	Build(root<<1,l,m);        //左子树
	Build((root<<1)|1,m+1,r);  //右子树
}

void Update(int root,int pos)
{
	int m;

	TREE[root].cnt++;
	if(TREE[root].left==TREE[root].right) return ;
	m=(TREE[root].left+TREE[root].right)>>1;
	if(pos<=m) Update(root<<1,pos);  //左边
	else Update((root<<1)|1,pos);     //右边
}

int QUERY(int root,int l,int r)
{
	int m;

	if(TREE[root].left==l && TREE[root].right==r)
		return TREE[root].cnt;
	m=(TREE[root].left+TREE[root].right)>>1;
	if(r<=m) return QUERY(root<<1,l,r);      //左边
	else if(l>m) return QUERY((root<<1)|1,l,r); //右边
	else return QUERY(root<<1,l,m)+QUERY((root<<1)|1,m+1,r); //中间
}

int ans[N];
int main()
{
	int t,T,n,q,i,j;

	ios::sync_with_stdio(false);
	cin>>T;
	t=0;
	while(T--)
	{
		cin>>n>>q;
		for(i=0;i<n;i++)
		{
			cin>>node[i].val;
			node[i].pos=i+1;
		}
		for(i=0;i<q;i++)
		{
			query[i].id=i;
			cin>>query[i].l>>query[i].r>>query[i].h;
		}
		sort(node,node+n);
		sort(query,query+q);
		Build(1,1,n);
		cout<<"Case "<<++t<<":"<<endl;
		for(i=0,j=0;i<q;i++)
		{
			while(j<n && node[j].val<=query[i].h)
			{
				Update(1,node[j].pos);
				j++;
			}
			ans[query[i].id]=QUERY(1,query[i].l+1,query[i].r+1);
		}
		for(i=0;i<q;i++)
			cout<<ans[i]<<endl;
	}
    return 0;
}
时间: 2024-10-09 07:58:42

HDU ACM 4417 Super Mario 离线线段树的相关文章

HDU 4417 Super Mario(离线线段树or树状数组)

Problem Description Mario is world-famous plumber. His "burly" figure and amazing jumping ability reminded in our memory. Now the poor princess is in trouble again and Mario needs to save his lover. We regard the road to the boss's castle as a l

hdu 4417 Super Mario (线段树+动态数组)

Super Mario Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) Total Submission(s): 2685    Accepted Submission(s): 1306 Problem Description Mario is world-famous plumber. His "burly" figure and amazing jumping a

Super Mario(线段树离线区间k值)

以前见过这题,没做出来,知道是离线处理,这次仔细想了下, 首先把出现的高度都map离散化一下,以离散化出来的数目g建树,把每个位置都开俩个vector,一个存以这个位置为L的询问,一个存以这个位置为R的询问. 然后从1-g 进行更新,假如当前i是以第j个区间的开始位置,那么这时就可以询问一下<=p[j].h的个数s,显然这时第J个区间多加的,需要减掉,p[j].sum-=s; 然后更新第i个数,update(a[i],1,g,1);再找到某第k区间是以i结尾的,那么依旧询问一下,得出s,p[k]

hdu 4417 Super Mario(离线树状数组|划分树)

Super Mario Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) Total Submission(s): 2584    Accepted Submission(s): 1252 Problem Description Mario is world-famous plumber. His "burly" figure and amazing jumping a

HDU 4417 Super Mario(主席树求区间内的区间查询+离散化)

Super Mario Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) Total Submission(s): 5101    Accepted Submission(s): 2339 Problem Description Mario is world-famous plumber. His “burly” figure and amazing jumping abilit

HDU 4417 Super Mario (划分树)(二分)

Super Mario Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)Total Submission(s): 6077    Accepted Submission(s): 2645 Problem Description Mario is world-famous plumber. His "burly" figure and amazing jumping ab

hdu 4417 Super Mario(主席树)

题意:给你一些数,有多次询问,问你在l,r区间内小于k的数有多少个 思路:主席树大发好,虽然树状数组和线段树离线也可以做 代码: #include <set> #include <map> #include <queue> #include <stack> #include <math.h> #include <vector> #include <string> #include <stdio.h> #incl

HDOJ题目4417 Super Mario(划分树求区间比k小的个数+二分)

Super Mario Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) Total Submission(s): 3313    Accepted Submission(s): 1548 Problem Description Mario is world-famous plumber. His "burly" figure and amazing jumping a

hdu 4417 Super Mario (主席树)

链接:http://acm.hdu.edu.cn/showproblem.php?pid=4417 题意: 给你段长为n的序列,有q个询问,每次询问区间[l.r]内有多少个数小于等于k 思路: 之前用分块写过类似的,不过为了练习下主席树,这里用主席树写了下.思路很简单 离线离散化处理下,每次插入一个数num时,在主席树上下标num+1,这样每次询问[l,r]中有多少个小于k的数的时候,我们只要找下标[1,k]的区间第R次修改后的总和减去第L-1次修改后的总值就可以得到了 实现代码: #inclu