Home_W的难题4
TimeLimit:1000MS MemoryLimit:128MB
64-bit integer IO format:%lld
已解决 | 已收藏(备注:树状数组或主席树) | 已有3人收藏了本题
Problem Description
给一个数列a1,a2,……an
查询在[l,r]区间内,大于等于x的数有多少个
Input
单组数据
第一个是两个整数n,q的代表数字的个数和查询的个数
接下来一行有n个数,a1,a2,……an
在接下来q行,每行有三个整数l,r,x;
n,q<=1e5
0<=ai,x<=1e5
1<=l<=r<=n
Output
对于每个查询输出相应的结果
SampleInput
10 10 5 1 3 10 5 3 2 9 0 9 5 7 1 1 6 1 1 10 6 2 6 8 1 5 3 6 10 8 1 3 5 2 5 7 4 8 8 5 9 0
SampleOutput
3 6 3 1 4 2 1 1 2 5
1 #include <iostream> 2 #include <cstring> 3 #include <cstdio> 4 #include <algorithm> 5 #include <vector> 6 using namespace std; 7 const int maxn=1e5+5; 8 int n,m,x,y,k,cnt; 9 int a[maxn],root[maxn]; 10 struct Node{ int l,r,sum; }A[maxn*24]; 11 vector<int> vec; 12 13 int getid(int x) { return lower_bound(vec.begin(),vec.end(),x)-vec.begin()+1; } 14 void updata(int l,int r,int &now,int pre,int pos){ 15 A[++cnt]=A[pre];now=cnt;A[now].sum++; 16 if(l==r) return; 17 int mid=l+r>>1; 18 if(mid>=pos) updata(l,mid,A[now].l,A[pre].l,pos); 19 else updata(mid+1,r,A[now].r,A[pre].r,pos); 20 } 21 22 int query(int l,int r,int x,int y,int num){ 23 if(r<num) return 0; 24 if(l>=num) return A[y].sum-A[x].sum; 25 int mid=l+r>>1; 26 return query(l,mid,A[x].l,A[y].l,num)+query(mid+1,r,A[x].r,A[y].r,num); 27 } 28 29 int main(){ 30 scanf("%d%d",&n,&m); 31 for(int i=1;i<=n;i++) scanf("%d",&a[i]),vec.push_back(a[i]); 32 sort(vec.begin(),vec.end());vec.erase(unique(vec.begin(),vec.end()),vec.end()); 33 for(int i=1;i<=n;i++) updata(1,n,root[i],root[i-1],getid(a[i])); 34 vec.push_back(100000005); 35 for(int i=1;i<=m;i++){ 36 scanf("%d%d%d",&x,&y,&k); 37 printf("%d ",query(1,n,root[x-1],root[y],getid(k))); 38 } 39 return 0; 40 }