huangriq

导航

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 }

 

posted on 2012-09-30 14:46  huangriq  阅读(244)  评论(0编辑  收藏  举报