题意:输入一个长度为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 }

转载于:https://www.cnblogs.com/huangriq/archive/2012/09/30/2709212.html

hdu 4417(线段树OR树状数组)相关推荐

  1. HDU 4417 Super Mario(划分树)

    Super Mario Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) Tota ...

  2. HDU 4417 Super Mario(离线 + 树状数组)

    题目: Mario is world-famous plumber. His "burly" figure and amazing jumping ability reminded ...

  3. HDU - 4417 Super Mario(主席树/线段树+离线)

    题目链接:点击查看 题目大意:给出由 n 个数的数列,再给出 m 次查询,每次查询需要输出 [ l , r ] 内小于等于 h 的数有多少个 题目分析:大晚上睡不着觉随便做做题,发现这个题目原来可以用 ...

  4. hdu 4417 Super Mario 划分树+二分

    http://acm.hdu.edu.cn/showproblem.php?pid=4417 题意: 给定一个长度为n的序列,求区间[L,R]中小于h的个数: 思路: 分三种情况: 1:如果该区间最小 ...

  5. #HDU 4417 Super Mario (主席树 + 二分)

    Super Mario Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) Tota ...

  6. HDU 4417 Super Mario(划分树问题求不大于k的数有多少)

    Super Mario Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) Tota ...

  7. HDU 4417 Super Mario(线段树||树状数组+离线操作 之线段树篇)

    Mario is world-famous plumber. His "burly" figure and amazing jumping ability reminded in ...

  8. HDU 4417 Super Mario(离线线段树or树状数组)

    Problem Description Mario is world-famous plumber. His "burly" figure and amazing jumping ...

  9. HDU 4031 Attack(线段树/树状数组区间更新单点查询+暴力)

    Attack Time Limit: 5000/3000 MS (Java/Others)    Memory Limit: 65768/65768 K (Java/Others) Total Sub ...

最新文章

  1. 295. 数据流的中位数
  2. throw和throw ex的区别
  3. 学python最好的方式-自学Python有什么好方法吗?老男孩专业Python培训
  4. 数据库access和mysql_数据库access和MYSQL有什么区别?
  5. PAT甲级1005 Spell It Right :[C++题解]字符串处理
  6. linux下rpm方式安装mysql5.6及问题解决
  7. 模型图像ASM(Active Shape Model) 主动形状模型总结
  8. ORACLE数据库的连接
  9. html中使用过渡不显示,CSS3过渡不适用于显示属性
  10. AndroidTv开发中常用的adb命令
  11. Java从入门到精通入职学习路线
  12. adb重启是什么意思
  13. Java 常用数据类型(总结)
  14. Day 12 - 标签图片的方法与实作
  15. 存量用户时代,方兴未艾的客户服务SaaS
  16. 阿里云安全组设定(虚拟机端口打开)
  17. 【真.干货】一篇文章了解关于计算机硬件那些事
  18. FPGA解码4line MIPI视频 IMX291/IMX290摄像头采集 提供工程源码和技术支持
  19. 电路习题解答 第四章 4-25
  20. 在线翻译软件:我为什么选择了memoQ?

热门文章

  1. python画折线图代码-python绘制简单折线图代码示例
  2. python网络爬虫的基本步骤-Python网络爬虫与信息提取(一)(入门篇)
  3. 从零开始学python网络爬虫-从零开始学Python 三(网络爬虫)
  4. python 画图 内存-python的内存分析和处理
  5. 自学python需要多长时间-Python学习步骤如何安排?多长时间可以学会精通呢?
  6. python基础题库-Python题库
  7. php和python对比-PHP和Python性能比较:放弃PHP改用Python
  8. python下载后如何使用-如何使用python下载文件?
  9. 自学python转行-转行学习python 需要多久?应该如何学习?
  10. 如何用python画圆形的代码-Python实现的圆形绘制(画圆)示例