zoukankan      html  css  js  c++  java
  • hdu 4417(线段树OR树状数组)

    题意:输入一个长度为n的序列,然后m个询问,询问区间[a,b]中比h小的数的个数。

    思路:树状数组或线段树离线处理。

    树状数组1

    View Code
     1 #include<cstdio>
     2 #include<iostream>
     3 #include<algorithm>
     4 #include<cstring>
     5 #include<cmath>
     6 #include<map>
     7 using namespace std;
     8 #define rep(i,a,b) for(int i=(a);i<=(b);i++)
     9 #define repd(i,a,b) for(int i=(a);i>=(b);i--)
    10 #define N 100010
    11 typedef __int64 ll;
    12 int c[N],val[N];
    13 struct edge{
    14     int a,b,w,pos;
    15 }e[N*2];
    16 bool cmp(edge a,edge b){
    17     if(a.w==b.w){
    18         return a.pos<b.pos;
    19     }
    20     return a.w<b.w;
    21 }
    22 int lowbit(int x){
    23     return x&(-x);
    24 }
    25 int sum(int pos){
    26     int s=0;
    27     while(pos>0){
    28         s+=c[pos];
    29         pos-=lowbit(pos);
    30     }
    31     return s;
    32 }
    33 void add(int pos,int x,int n){
    34     while(pos<=n){
    35         c[pos]+=x;
    36         pos+=lowbit(pos);
    37     }
    38 }
    39 int main(){
    40     int ca,cas=1;
    41     scanf("%d",&ca);
    42     while(ca--){
    43         memset(c,0,sizeof(c));
    44         int n,m;
    45         scanf("%d%d",&n,&m);
    46         rep(i,1,n){
    47             scanf("%d",&e[i].w);
    48             e[i].a=e[i].b=-1;
    49             e[i].pos=i;
    50         }
    51         rep(i,n+1,m+n){
    52             scanf("%d%d%d",&e[i].a,&e[i].b,&e[i].w);
    53             e[i].pos=i;
    54         }
    55         sort(e+1,e+m+n+1,cmp);
    56         rep(i,1,m+n){
    57             if(e[i].pos>n){
    58                 val[e[i].pos-n]=sum(e[i].b+1)-sum(e[i].a);
    59             }
    60             else add(e[i].pos,1,n);
    61         }
    62         printf("Case %d:\n",cas++);
    63         rep(i,1,m){
    64             printf("%d\n",val[i]);
    65         }
    66     }
    67     return 0;
    68 }

    树状数组2

    View Code
     1 #include<cstdio>
     2 #include<iostream>
     3 #include<algorithm>
     4 #include<cstring>
     5 #include<cmath>
     6 #include<map>
     7 using namespace std;
     8 #define rep(i,a,b) for(int i=(a);i<=(b);i++)
     9 #define repd(i,a,b) for(int i=(a);i>=(b);i--)
    10 #define N 100010
    11 typedef __int64 ll;
    12 int c[N],val[N];
    13 struct edge{
    14     int a,b,w,pos;
    15 }e[N*2];
    16 bool cmp(edge a,edge b){
    17     if(a.w==b.w){
    18         return a.pos<b.pos;
    19     }
    20     return a.w<b.w;
    21 }
    22 struct Tary{
    23     int c[N];
    24     void init(){
    25         memset(c,0,sizeof(c));
    26     }
    27     int lowbit(int x){
    28         return x&(-x);
    29     }
    30     int sum(int pos){
    31         int s=0;
    32         for(int i=pos;i>0;i-=lowbit(i))s+=c[i];
    33         return s;
    34     }
    35     void add(int pos,int x,int n){
    36         for(int i=pos;i<=n;i+=lowbit(i))c[i]+=x;
    37     }
    38 }tre;
    39 int main(){
    40     int ca,cas=1;
    41     scanf("%d",&ca);
    42     while(ca--){
    43         tre.init();
    44         int n,m;
    45         scanf("%d%d",&n,&m);
    46         rep(i,1,n){
    47             scanf("%d",&e[i].w);
    48             e[i].a=e[i].b=-1;
    49             e[i].pos=i;
    50         }
    51         rep(i,n+1,m+n){
    52             scanf("%d%d%d",&e[i].a,&e[i].b,&e[i].w);
    53             e[i].pos=i;
    54         }
    55         sort(e+1,e+m+n+1,cmp);
    56         rep(i,1,m+n){
    57             if(e[i].pos>n){
    58                 val[e[i].pos-n]=tre.sum(e[i].b+1)-tre.sum(e[i].a);
    59             }
    60             else tre.add(e[i].pos,1,n);
    61         }
    62         printf("Case %d:\n",cas++);
    63         rep(i,1,m){
    64             printf("%d\n",val[i]);
    65         }
    66     }
    67     return 0;
    68 }

    线段树

    View Code
     1 #include<cstdio>
     2 #include<iostream>
     3 #include<algorithm>
     4 #include<cstring>
     5 #include<cmath>
     6 #include<map>
     7 using namespace std;
     8 #define rep(i,a,b) for(int i=(a);i<=(b);i++)
     9 #define repd(i,a,b) for(int i=(a);i>=(b);i--)
    10 #define lson a,m,k<<1
    11 #define rson m+1,b,k<<1|1
    12 #define N 100010
    13 typedef __int64 ll;
    14 int val[N];
    15 struct edge{
    16     int a,b,w,pos;
    17 }e[N*2];
    18 bool cmp(edge a,edge b){
    19     if(a.w==b.w){
    20         return a.pos<b.pos;
    21     }
    22     return a.w<b.w;
    23 }
    24 struct SegTre{
    25     struct Treenode{
    26         int a,b,sum;
    27     }tree[N*3];
    28     void pushup(int k){
    29         tree[k].sum=tree[k<<1].sum+tree[k<<1|1].sum;
    30     }
    31     void bulid(int a,int b,int k){
    32         tree[k].a=a,tree[k].b=b,tree[k].sum=0;
    33         if(a==b)return ;
    34         int m=(a+b)>>1;
    35         bulid(lson);bulid(rson);pushup(k);
    36     }
    37     void update(int pos,int a,int b,int k){
    38         if(a==b){tree[k].sum+=1;return ;}
    39         int m=(a+b)>>1;
    40         if(pos<=m)update(pos,lson);
    41         else update(pos,rson);
    42         pushup(k);
    43     }
    44     int query(int c,int d,int a,int b,int k){
    45         if(c<=a&&d>=b)return tree[k].sum;
    46         int m=(a+b)>>1;
    47         int t=0;
    48         if(c<=m)t=query(c,d,lson);
    49         if(d>m)t+=query(c,d,rson);
    50         return t;
    51     }
    52 }tre;
    53 int main(){
    54     int ca,cas=1;
    55     scanf("%d",&ca);
    56     while(ca--){
    57 
    58         int n,m;
    59         scanf("%d%d",&n,&m);
    60         tre.bulid(1,n,1);
    61         rep(i,1,n){
    62             scanf("%d",&e[i].w);
    63             e[i].a=e[i].b=-1;
    64             e[i].pos=i;
    65         }
    66         rep(i,n+1,m+n){
    67             scanf("%d%d%d",&e[i].a,&e[i].b,&e[i].w);
    68             e[i].pos=i;
    69         }
    70         sort(e+1,e+m+n+1,cmp);
    71         rep(i,1,m+n){
    72             if(e[i].pos>n){
    73                 val[e[i].pos-n]=tre.query(e[i].a+1,e[i].b+1,1,n,1);
    74             }
    75             else tre.update(e[i].pos,1,n,1);
    76         }
    77         printf("Case %d:\n",cas++);
    78         rep(i,1,m){
    79             printf("%d\n",val[i]);
    80         }
    81     }
    82     return 0;
    83 }

    划分树+二分

    View Code
     1 #include<iostream>
     2 #include<algorithm>
     3 #include<cstdio>
     4 #include<cstring>
     5 #include<cmath>
     6 using namespace std;
     7 #define rep(i,a,b) for(int i=(a);i<=(b);i++)
     8 #define lson L,M,dep+1
     9 #define rson M+1,R,dep+1
    10 #define N 100010
    11 struct PartTree{
    12     int sorted[N];
    13     int toleft[30][N];
    14     int tree[30][N];
    15     void init(int n){
    16         rep(i,1,n)tree[0][i]=sorted[i];
    17         sort(sorted+1,sorted+n+1);
    18     }
    19     void bulid(int L,int R,int dep){
    20         if(L==R)return ;
    21         int M=(L+R)>>1,same=M-L+1;
    22         rep(i,L,R){
    23             if(sorted[M]>tree[dep][i])same--;
    24         }
    25         int lpos=L,rpos=M+1;
    26         rep(i,L,R){
    27             if(tree[dep][i]<sorted[M])tree[dep+1][lpos++]=tree[dep][i];
    28             else if(sorted[M]==tree[dep][i]&&same)tree[dep+1][lpos++]=tree[dep][i],same--;
    29             else tree[dep+1][rpos++]=tree[dep][i];
    30             toleft[dep][i]=toleft[dep][L-1]+lpos-L;
    31         }
    32         bulid(lson);
    33         bulid(rson);
    34     }
    35     int query(int L,int R,int dep,int l,int r,int k){
    36         if(l==r)return tree[dep][l];
    37         int M=(L+R)>>1;
    38         int cnt=toleft[dep][r]-toleft[dep][l-1];
    39         if(cnt>=k){
    40             int newl=L+toleft[dep][l-1]-toleft[dep][L-1];
    41             int newr=newl+cnt-1;
    42             return query(lson,newl,newr,k);
    43         }
    44         else {
    45             int newr=r+toleft[dep][R]-toleft[dep][r];
    46             int newl=newr-(r-l-cnt);
    47             return query(rson,newl,newr,k-cnt);
    48         }
    49     }
    50 }tre;
    51 int slove(int a,int b,int w,int n){
    52     int left=1,right=b-a+1;
    53     while(left<right){
    54         int mid=(left+right)>>1;
    55         int t=tre.query(1,n,0,a,b,mid);
    56         if(t>w)right=mid;
    57         else left=mid+1;
    58     }
    59     if(tre.query(1,n,0,a,b,left)>w)return left-1;
    60     return left;
    61 }
    62 int main(){
    63     int ca,cas=1;
    64     scanf("%d",&ca);
    65     while(ca--){
    66         int n,m;
    67         scanf("%d%d",&n,&m);
    68         rep(i,1,n){
    69             scanf("%d",&tre.sorted[i]);
    70         }
    71         tre.init(n);
    72         tre.bulid(1,n,0);
    73         printf("Case %d:\n",cas++);
    74         rep(i,1,m){
    75             int a,b,w;
    76             scanf("%d%d%d",&a,&b,&w);
    77             printf("%d\n",slove(a+1,b+1,w,n));
    78         }
    79     }
    80     return 0;
    81 }

    划分树变形

    View Code
     1 #include<iostream>
     2 #include<algorithm>
     3 #include<cstdio>
     4 #include<cstring>
     5 #include<cmath>
     6 using namespace std;
     7 #define rep(i,a,b) for(int i=(a);i<=(b);i++)
     8 #define lson L,M,dep+1
     9 #define rson M+1,R,dep+1
    10 #define N 100010
    11 struct PartTree{
    12     int sorted[N];
    13     int toleft[30][N];
    14     int tree[30][N];
    15     void init(int n){
    16         rep(i,1,n)tree[0][i]=sorted[i];
    17         sort(sorted+1,sorted+n+1);
    18     }
    19     void bulid(int L,int R,int dep){
    20         if(L==R)return ;
    21         int M=(L+R)>>1,same=M-L+1;
    22         rep(i,L,R){
    23             if(sorted[M]>tree[dep][i])same--;
    24         }
    25         int lpos=L,rpos=M+1;
    26         rep(i,L,R){
    27             if(tree[dep][i]<sorted[M])tree[dep+1][lpos++]=tree[dep][i];
    28             else if(sorted[M]==tree[dep][i]&&same)tree[dep+1][lpos++]=tree[dep][i],same--;
    29             else tree[dep+1][rpos++]=tree[dep][i];
    30             toleft[dep][i]=toleft[dep][L-1]+lpos-L;
    31         }
    32         bulid(lson);
    33         bulid(rson);
    34     }
    35     int query(int L,int R,int dep,int l,int r,int w){
    36         if(l==r)return tree[dep][l]<=w?1:0;
    37         else if(l>r)return 0;
    38         int M=(L+R)>>1;
    39         int cnt=toleft[dep][r]-toleft[dep][l-1];
    40         if(sorted[M]>w){
    41             int newl=L+toleft[dep][l-1]-toleft[dep][L-1];
    42             int newr=newl+cnt-1;
    43             return query(lson,newl,newr,w);
    44         }
    45         else {
    46             int newr=r+toleft[dep][R]-toleft[dep][r];
    47             int newl=newr-(r-l-cnt);
    48             return query(rson,newl,newr,w)+cnt;
    49         }
    50     }
    51 }tre;
    52 int slove(int a,int b,int w,int n){
    53     return tre.query(1,n,0,a,b,w);
    54 }
    55 int main(){
    56     int ca,cas=1;
    57     scanf("%d",&ca);
    58     while(ca--){
    59         int n,m;
    60         scanf("%d%d",&n,&m);
    61         rep(i,1,n){
    62             scanf("%d",&tre.sorted[i]);
    63         }
    64         tre.init(n);
    65         tre.bulid(1,n,0);
    66         printf("Case %d:\n",cas++);
    67         rep(i,1,m){
    68             int a,b,w;
    69             scanf("%d%d%d",&a,&b,&w);
    70             printf("%d\n",slove(a+1,b+1,w,n));
    71         }
    72     }
    73     return 0;
    74 }
  • 相关阅读:
    封装cookie
    敏感词过滤
    面向对象改成选项卡
    正则表达式
    cookie
    DOM
    系统对象
    cookie记录用户名
    6个原则
    23中设计模式
  • 原文地址:https://www.cnblogs.com/huangriq/p/2709212.html
Copyright © 2011-2022 走看看