题意:给你一些数,有多次询问,问你在l,r区间内小于k的数有多少个
思路:主席树大发好,虽然树状数组和线段树离线也可以做
代码:
#include <set> #include <map> #include <queue> #include <stack> #include <math.h> #include <vector> #include <string> #include <stdio.h> #include <string.h> #include <stdlib.h> #include <iostream> #include <algorithm> #define zero(a) fabs(a)<eps #define max( x, y ) ( ((x) > (y)) ? (x) : (y) ) #define min( x, y ) ( ((x) < (y)) ? (x) : (y) ) #define lowbit(x) (x&(-x)) #define debug(a) cerr<<#a<<"=="<<a<<endl typedef long long LL; const double pi=acos(-1.0); const double eps=1e-8; const int inf=0x3f3f3f3f; const LL linf=0x3f3f3f3f3f3f3f3f; using namespace std; const int maxn=100007; int n,m,a[maxn],root[maxn],cnt,x,y,k; struct node { int l,r,sum; }T[maxn*40]; vector<int>v; int getid(int x) { return lower_bound(v.begin(),v.end(),x)-v.begin(); } void update(int l,int r,int &x,int y,int pos) { T[++cnt]=T[y],T[cnt].sum++,x=cnt; if(l==r)return ; int mid=(l+r)>>1; if(pos<=mid)update(l,mid,T[x].l,T[y].l,pos); else update(mid+1,r,T[x].r,T[y].r,pos); } int query(int l,int r,int x,int y,int L,int R) { if(L>R) return 0; if(L<=l && r<=R){ return T[y].sum-T[x].sum; } int mid=(l+r)>>1,ans=0; if(L<=mid) ans+=query(l,mid,T[x].l,T[y].l,L,R); if(R>mid) ans+=query(mid+1,r,T[x].r,T[y].r,L,R); return ans; } int main() { int tt; scanf("%d",&tt); int cas=1; while(tt--){ scanf("%d%d",&n,&m); v.clear(); for(int i=1;i<=n;i++){ scanf("%d",&a[i]); v.push_back(a[i]); } sort(v.begin(),v.end()); v.erase(unique(v.begin(),v.end()),v.end()); for(int i=1;i<=n;i++){ update(0,v.size()-1,root[i],root[i-1],getid(a[i])); } printf("Case %d:\n",cas++); int t1,t2,t3; while(m--){ scanf("%d%d%d",&t1,&t2,&t3); int pos=upper_bound(v.begin(),v.end(),t3)-v.begin()-1; printf("%d\n",query(0,v.size()-1,root[t1],root[t2+1],0,pos)); } } return 0; }
原文地址:https://www.cnblogs.com/lalalatianlalu/p/8855114.html
时间: 2024-11-10 16:19:12