查询区间里有多少个小于k的数
用主席树可以在线做,树状数组只能离线。
先放个主席树的。
1 #include<cstdio> 2 #include<iostream> 3 #include<algorithm> 4 #include<queue> 5 #include<set> 6 #include<string> 7 #include<cmath> 8 #include<cstring> 9 #define FF first 10 #define SS second 11 #define ll long long 12 #define pb push_back 13 #define pm make_pair 14 using namespace std; 15 typedef pair<int,int> PII; 16 const int MAX = 1e5 + 5; 17 struct TREE { 18 int l,r; 19 int val; 20 } tr[MAX*40]; 21 22 int tot; 23 int a[MAX],b[MAX]; 24 int root[MAX]; 25 int build(int l,int r) { 26 int cur = ++tot; 27 tr[cur].val = 0; 28 if(l == r) { 29 tr[cur].l = tr[cur].r = 0;//这一步好像没啥用? 30 return cur; 31 } 32 int m = (l+r)>>1; 33 tr[cur].l = build(l,m); 34 tr[cur].r = build(m+1,r); 35 return cur; 36 } 37 void pushup(int cur) { 38 tr[cur].val = tr[tr[cur].l].val + tr[tr[cur].r].val; 39 } 40 int update(int pre,int tar,int l,int r) { 41 int cur = ++tot; 42 tr[cur] = tr[pre]; 43 if(l == r) { 44 tr[cur].val++; 45 return cur; 46 } 47 int m = (l+r)>>1; 48 if(tar <= m) tr[cur].l = update(tr[pre].l,tar,l,m); 49 else tr[cur].r = update(tr[pre].r,tar,m+1,r); 50 pushup(cur); 51 return cur; 52 } 53 int query(int pl,int pr,int l,int r,int H) { 54 if(l == r) return tr[pr].val - tr[pl].val; 55 int m = (l+r)>>1; 56 if(H <= m) return query(tr[pl].l,tr[pr].l,l,m,H); 57 else return tr[tr[pr].l].val - tr[tr[pl].l].val + query(tr[pl].r,tr[pr].r,m+1,r,H); 58 } 59 int main() 60 { 61 int n,m; 62 int t,iCase=0; 63 cin>>t; 64 while(t--) { 65 printf("Case %d:\n",++iCase); 66 cin>>n>>m; 67 tot=0; 68 for(int i = 1; i<=n; i++) scanf("%d",a+i),b[i] = a[i]; 69 root[0] = build(1,n); 70 sort(b+1,b+n+1); 71 int LEN = unique(b+1,b+n+1) - b - 1; 72 for(int i = 1; i<=n; i++) { 73 int pos = lower_bound(b+1,b+LEN+1,a[i]) - b; 74 root[i] = update(root[i-1],pos,1,n); 75 } 76 while(m--) { 77 int l,r,H; 78 scanf("%d%d%d",&l,&r,&H);l++,r++; 79 int pos = upper_bound(b+1,b+LEN+1,H) - b - 1; 80 if(pos) printf("%d\n",query(root[l-1],root[r],1,n,pos)); 81 else printf("0\n"); 82 } 83 } 84 return 0 ; 85 }
再放一个树状数组的。
1 #include<iostream> 2 #include<cstdio> 3 #include<cstring> 4 #include<cmath> 5 #include<algorithm> 6 using namespace std; 7 const int maxm=1e5+5; 8 struct Data{ 9 int num,id; 10 bool operator<(const Data a){//按数值大小排序 11 return num<a.num; 12 } 13 }a[maxm]; 14 struct Query{ 15 int l,r,h,id; 16 bool operator<(const Query a){//按h排序 17 return h<a.h; 18 } 19 }q[maxm]; 20 int c[maxm];//BIT 21 int res[maxm];//存答案 22 int n,m; 23 int cas=1; 24 void init(){ 25 memset(c,0,sizeof c); 26 } 27 int lowbit(int i){ 28 return i&-i; 29 } 30 void add(int i,int x){ 31 while(i<=n){ 32 c[i]+=x; 33 i+=lowbit(i); 34 } 35 } 36 int ask(int i){ 37 int ans=0; 38 while(i){ 39 ans+=c[i]; 40 i-=lowbit(i); 41 } 42 return ans; 43 } 44 void input(){ 45 scanf("%d%d",&n,&m); 46 for(int i=1;i<=n;i++){ 47 scanf("%d",&a[i].num); 48 a[i].id=i; 49 } 50 for(int i=1;i<=m;i++){ 51 scanf("%d%d%d",&q[i].l,&q[i].r,&q[i].h); 52 q[i].l++,q[i].r++;//题目区间从0开始,加1变为从1开始 53 q[i].id=i; 54 } 55 sort(a+1,a+1+n); 56 sort(q+1,q+1+m); 57 } 58 void solve(){ 59 printf("Case %d:\n",cas++); 60 int last=1; 61 for(int i=1;i<=m;i++){ 62 while(q[i].h>=a[last].num&&last<=n){//把数值比h小的插入 63 add(a[last].id,1);//插入的是编号 64 last++; 65 } 66 res[q[i].id]=ask(q[i].r)-ask(q[i].l-1); 67 } 68 for(int i=1;i<=m;i++){ 69 printf("%d\n",res[i]); 70 } 71 } 72 int main(){ 73 int T; 74 scanf("%d",&T); 75 while(T--){ 76 init(); 77 input(); 78 solve(); 79 } 80 return 0; 81 }
HDU 4417,板题。
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】凌霞软件回馈社区,博客园 & 1Panel & Halo 联合会员上线
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】博客园社区专享云产品让利特惠,阿里云新客6.5折上折
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· DeepSeek 解答了困扰我五年的技术问题
· 为什么说在企业级应用开发中,后端往往是效率杀手?
· 用 C# 插值字符串处理器写一个 sscanf
· Java 中堆内存和栈内存上的数据分布和特点
· 开发中对象命名的一点思考
· 为什么说在企业级应用开发中,后端往往是效率杀手?
· DeepSeek 解答了困扰我五年的技术问题。时代确实变了!
· 本地部署DeepSeek后,没有好看的交互界面怎么行!
· 趁着过年的时候手搓了一个低代码框架
· 推荐一个DeepSeek 大模型的免费 API 项目!兼容OpenAI接口!