InputThe 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.)OutputFor 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
1 10 10 0 5 2 7 5 4 3 8 7 7 2 8 6 3 5 0 1 3 1 1 9 4 0 1 0 3 5 5 5 5 1 4 6 3 1 5 7 5 7 3
Sample Output
Case 1: 4 0 0 3 1 2 0 1 5 1
求一个区间比小于等于K的个数 我们就可以去查询第R个版本的线段树-第L-1个版本的线段树的数量
代码:
#include<cstdio> #include<iostream> #include<cstring> #include<algorithm> #include<queue> #include<stack> #include<set> #include<map> #include<vector> #include<cmath> const int maxn=1e5+5; typedef long long ll; using namespace std; struct node { int l,r; int sum; }tree[maxn*20]; int cnt,root[maxn]; int a[maxn]; vector<int>v; int getid(int x) { return lower_bound(v.begin(),v.end(),x)-v.begin()+1; } void build(int &u,int l,int r) { u=++cnt; tree[u].sum=0; if(l==r)return ; int mid=(l+r)/2; build(tree[u].l,l,mid); build(tree[u].r,mid+1,r); } void update(int l,int r,int pre,int &now,int p) { tree[++cnt]=tree[pre]; now=cnt; tree[now].sum++; if(l==r) { return ; } int mid=(l+r)>>1; if(p<=mid) { update(l,mid,tree[pre].l,tree[now].l,p); } else { update(mid+1,r,tree[pre].r,tree[now].r,p); } } int query(int l,int r,int L,int R,int k) { if(l==r) { return tree[R].sum-tree[L].sum; } int mid=(l+r)>>1; if(k<=mid) { return query(l,mid,tree[L].l,tree[R].l,k); } else { ll ans=tree[tree[R].l].sum-tree[tree[L].l].sum; ans+=query(mid+1,r,tree[L].r,tree[R].r,k); return ans; } } int main() { int T; cin>>T; int cc=1; while(T--) { int n,m; scanf("%d%d",&n,&m); cnt=0; for(int t=1;t<=n;t++) { v.clear(); } for(int t=1;t<=n;t++) { scanf("%d",&a[t]); v.push_back(a[t]); } sort(v.begin(),v.end()); v.erase(unique(v.begin(),v.end()),v.end()); build(root[0],1,n); for(int t=1;t<=n;t++) { update(1,n,root[t-1],root[t],getid(a[t])); } int x,y,k; printf("Case %d:\n",cc++); while(m--) { scanf("%d%d%d",&x,&y,&k); k=upper_bound(v.begin(),v.end(),k)-v.begin(); if(k==0) { puts("0"); continue; } x++; y++; printf("%d\n",query(1,n,root[x-1],root[y],k)); } } return 0; }