马里奥是举世闻名的水管工。他“魁梧”的身材和惊人的跳跃能力让我们想起了。现在可怜的公主又遇到了麻烦,马里奥需要拯救他的爱人。我们将通往老板城堡的道路视为一条线(长度为 n),在每个整数点 i 上都有一块高度为 hi 的砖。现在的问题是,如果马里奥可以跳跃的最大高度是 H,那么 [L, R] 马里奥可以击中多少块砖。
输入
第一行后面跟着一个整数 T,即测试数据的数量。对于每个测试数据:
第一行包含两个整数n,m(1<=n<=10^5,1<=m<=10^5),n是道路的长度,m是查询的次数。
下一行包含 n 个整数,每个砖的高度,范围为 [0, 1000000000]。
接下来的 m 行,每行包含三个整数 L, R,H.( 0 <= L <= R < n 0 <= H <= 1000000000。
输出
对于每个案例,输出“Case X:”(X 是从 1 开始的案例编号),后跟 m 行,每行包含一个整数。第 i 个整数是 Mario 可以在第 i 个查询中击中的砖块数。思路
目标是找到查询区间[L,R]中比H小或者等于的数有多少个,那我们可以对数组离散化后建立权值主席树,sum数组表示对应权值[l,r]区间中的包含的已有数的个数,后续操作就比较常规了。
1 #define IO std::ios::sync_with_stdio(0),cin.tie(0),cout.tie(0) 2 #define bug(x) cout<<#x<<" is "<<x<<endl 3 #include <iostream> 4 #include <list> 5 #include <unordered_map> 6 #include <map> 7 #include <vector> 8 #include <sstream> 9 #include <cmath> 10 #include <algorithm> 11 #define iter ::iterator 12 using namespace std; 13 typedef long long ll; 14 typedef pair<int,int>P; 15 #define pb push_back 16 #define mk make_pair 17 #define se second 18 #define fi first 19 20 const ll mod=1e9+7; 21 const int N=1e5+5; 22 int n,q; 23 int a[N],b[N],rt[N*32],ls[N*32],rs[N*32],sum[N*32]; 24 int cnt; 25 void up(int &o,int pre,int l,int r,int val){ 26 o=++cnt; 27 ls[o]=ls[pre]; 28 rs[o]=rs[pre]; 29 sum[o]=sum[pre]+1; 30 if(l==r)return; 31 int m=(l+r)/2; 32 if(val<=m)up(ls[o],ls[pre],l,m,val); 33 else up(rs[o],rs[pre],m+1,r,val); 34 } 35 int qu(int o,int pre,int l,int r,int val){ 36 37 int res=sum[o]-sum[pre]; 38 //printf("%d %d %d\n",l,r,res); 39 if(r<=val)return res; 40 if(l>val)return 0; 41 if(l==r)return res; 42 int m=(l+r)/2; 43 res=qu(ls[o],ls[pre],l,m,val); 44 if(val>m)res+=qu(rs[o],rs[pre],m+1,r,val); 45 return res; 46 } 47 int main(){ 48 IO; 49 int T,Case=0; 50 cin>>T; 51 while(T--){ 52 cnt=0; 53 cin>>n>>q; 54 55 for(int i=0;i<n;i++)cin>>a[i],b[i]=a[i]; 56 sort(a,a+n); 57 int m=unique(a,a+n)-a; 58 for(int i=0;i<n;i++) b[i]=lower_bound(a,a+m,b[i])-a+1; 59 for(int i=1;i<=n;i++){ 60 up(rt[i],rt[i-1],1,m,b[i-1]); 61 } 62 cout<<"Case "<<++Case<<":"<<endl; 63 while(q--){ 64 int L,R,val; 65 cin>>L>>R>>val; 66 int x=val; 67 val=lower_bound(a,a+m,val)-a+1; 68 if(a[val-1]!=x)val--; 69 cout<<qu(rt[R+1],rt[L],1,m,val)<<endl; 70 } 71 printf("\n"); 72 } 73 }
标签:pre,val,int,化后,ls,hdu4417,权值,include,define From: https://www.cnblogs.com/ccsu-kid/p/18206303