Super Mario
Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)Total Submission(s): 8196 Accepted Submission(s): 3453
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 line (the length is n), on every integer point i there is a brick on height hi. Now the question is how many bricks in [L, R] Mario can hit if the maximal height he can jump is H.
Input
The first line follows an integer T, the number of test data.
For each test data:
The first line contains two integers n, m (1 <= n <=10^5, 1 <= m <= 10^5), n is the length of the road, m is the number of queries.
Next line contains n integers, the height of each brick, the range is [0, 1000000000].
Next m lines, each line contains three integers L, R,H.( 0 <= L <= R < n 0 <= H <= 1000000000.)
For each test data:
The first line contains two integers n, m (1 <= n <=10^5, 1 <= m <= 10^5), n is the length of the road, m is the number of queries.
Next line contains n integers, the height of each brick, the range is [0, 1000000000].
Next m lines, each line contains three integers L, R,H.( 0 <= L <= R < n 0 <= H <= 1000000000.)
Output
For each case, output "Case X: " (X is the case number starting from 1) followed by m lines, each line contains an integer. The ith integer is the number of bricks Mario can hit for the ith query.
Sample Input
110 100 5 2 7 5 4 3 8 7 7 2 8 63 5 01 3 11 9 40 1 03 5 55 5 14 6 31 5 75 7 3
Sample Output
Case 1:4003120151
Source
Recommend
题意:
给了一个区间,区间上每个点的石块有不同的高度,下面有M次询问,l,r,h代表马里奥在[l,r]区间以h为最大高度能撞到的石块个数。
思路:
用主席树来写,将插入和查询操作放在一起按照高度排一个序,这样就可以免去二分查找了。然后分别按照插入和查找来不同处理数据。
PS:再不敢把l,r放到结构体里了,疯狂MLE,还以为是卡主席树QAQ|
代码:
#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
const int maxn=1e5+5;
using namespace std;
int ans[maxn],root[maxn];
int cnt;
struct node
{
int ls,rs,sum;
}tr[maxn*20];
struct data
{
int l,r,id,f,h;
}q[2*maxn];
bool cmp(data a,data b)
{
if(a.h!=b.h)
return a.h<b.h;
return a.f<b.f;
}
int build(int l,int r)
{
int num=++cnt;
if(l==r) return num;
int mid=(l+r)/2;
tr[num].ls=build(l,mid);
tr[num].rs=build(mid+1,r);
return num;
}
int update(int l,int r,int pre,int x)
{
int num=++cnt;
tr[num]=tr[pre];
tr[num].sum++;
if(l==r) return num;
int mid=(l+r)/2;
if(x<=mid) tr[num].ls=update(l,mid,tr[pre].ls,x);
else tr[num].rs=update(mid+1,r,tr[pre].rs,x);
return num;
}
int query(int l,int r,int num,int x,int y)
{
if(x<=l&&r<=y) return tr[num].sum;
int sum=0;
int mid=(l+r)/2;
if(x<=mid) sum+=query(l,mid,tr[num].ls,x,y);
if(y>mid) sum+=query(mid+1,r,tr[num].rs,x,y);
return sum;
}
int main()
{
int t,n,m,cas=1,res;
scanf("%d",&t);
while(t--)
{
cnt=0,res=0;
memset(tr,0,sizeof(tr));
scanf("%d%d",&n,&m);
for(int i=1;i<=n;i++)
{
scanf("%d",&q[i].h);
q[i].id=i;
q[i].f=0;
}
for(int i=n+1;i<=n+m;i++)
{
scanf("%d%d%d",&q[i].l,&q[i].r,&q[i].h);
q[i].l++,q[i].r++;
q[i].f=1;
q[i].id=i-n;
}
sort(q+1,q+1+n+m,cmp);
root[0]=build(1,n);
for(int i=1;i<=n+m;i++)
{
if(q[i].f==0)
{
root[++res]=update(1,n,root[res-1],q[i].id);
}
else
{
ans[q[i].id]=query(1,n,root[res],q[i].l,q[i].r);
}
}
printf("Case %d:\n",cas++);
for(int i=1;i<=m;i++)
{
printf("%d\n",ans[i]);
}
}
return 0;
}
本文介绍了一种使用主席树优化的区间查询问题解决方案,应用于SuperMario游戏中的路径挑战。通过预处理不同高度的砖块分布,实现高效查询马里奥在特定路径与跳跃高度下可击打的砖块数量。
695

被折叠的 条评论
为什么被折叠?



