zoukankan      html  css  js  c++  java
  • 查询区间里有多少个小于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:
    ",++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
    ",query(root[l-1],root[r],1,n,pos));
    81             else printf("0
    ");
    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:
    ",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
    ",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,板题。

  • 相关阅读:
    基础练习 分解质因数
    基础练习 矩阵乘法
    基础练习 矩形面积交
    基础练习 完美的代价
    设计模式完结(7)--桥接模式----处理多维度变化
    设计模式完结(6)--适配器模式----不兼容结构的协调
    设计模式完结(5)-建造者模式
    设计模式完结(4)-原型模式
    设计模式完结(3)单例模式
    设计模式读完总结(2)工厂模式
  • 原文地址:https://www.cnblogs.com/St-Lovaer/p/13537779.html
Copyright © 2011-2022 走看看