hdu 4417 Super Mario(划分树)

来源:互联网 发布:地籍数据标准 编辑:程序博客网 时间:2024/06/08 18:00

Super Mario

Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)
Total Submission(s): 3859    Accepted Submission(s): 1780


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.)
 

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
 


n个数 m个查询 每次查询给出l s h求在区间[l,s]内 不比h大的数有几个

使用划分树的想法  二分h在区间中的大小排序值 求出h在这个区间中能排到第几大

#include <cstdio>#include <iostream>#include <cstring>#include <cmath>#include <algorithm>#include <string.h>#include <string>#include <vector>#include <queue>#define MEM(a,x) memset(a,x,sizeof a)#define eps 1e-8#define MOD 10009#define MAXN 100010#define MAXM 100010#define INF 99999999#define ll __int64#define bug cout<<"here"<<endl#define fread freopen("ceshi.txt","r",stdin)#define fwrite freopen("out.txt","w",stdout)using namespace std;int tree[20][MAXN];int sorted[MAXN];int toleft[20][MAXN];void build(int l,int r,int dep){if(l==r) return;int mid=(l+r)/2;int same=mid-l+1;for(int i=l;i<=r;i++)if(tree[dep][i]<sorted[mid])same--;int lpos=l;int rpos=mid+1;for(int i=l;i<=r;i++){if(tree[dep][i]<sorted[mid])tree[dep+1][lpos++]=tree[dep][i];else if(tree[dep][i]==sorted[mid]&&same>0){tree[dep+1][lpos++]=tree[dep][i];same--;}elsetree[dep+1][rpos++]=tree[dep][i];toleft[dep][i]=toleft[dep][l-1]+lpos-l;}build(l,mid,dep+1);build(mid+1,r,dep+1);}int query(int L,int R,int l,int r,int dep,int k){if(l==r) return tree[dep][l];int mid=(L+R)/2;int cnt=toleft[dep][r]-toleft[dep][l-1];if(cnt>=k){int newl=L+toleft[dep][l-1]-toleft[dep][L-1];int newr=newl+cnt-1;return query(L,mid,newl,newr,dep+1,k);}else{int newr=r+toleft[dep][R]-toleft[dep][r];int newl=newr-(r-l-cnt);return query(mid+1,R,newl,newr,dep+1,k-cnt);}}int solve(int n,int l,int r,int h){int ans=0;int s=1;int t=(r-l)+1;int mid;while(s<=t){mid=(s+t)/2;int q=query(1,n,l,r,0,mid);if(q<=h){s=mid+1;ans=mid;}elset=mid-1;}return ans;}int main(){//    freopen("ceshi.txt","r",stdin);int tc;scanf("%d",&tc);int cs=1;while(tc--){int n,m;scanf("%d%d",&n,&m);MEM(tree,0);for(int i=1;i<=n;i++){scanf("%d",&tree[0][i]);sorted[i]=tree[0][i];}sort(sorted+1,sorted+n+1);build(1,n,0);printf("Case %d:\n",cs++);while(m--){int l,r,h;scanf("%d%d%d",&l,&r,&h);l++; r++;int ans=solve(n,l,r,h);printf("%d\n",ans);}}return 0;}







0 0
原创粉丝点击