51nod 1287 线段树

Posted zzq

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了51nod 1287 线段树相关的知识,希望对你有一定的参考价值。

http://www.51nod.com/onlineJudge/questionCode.html#!problemId=1287

简单的线段树题目,直接写个二分查找大于等于x的最小位置就好了。

 1 #include<bits/stdc++.h>
 2 using namespace std;
 3 #define inf 0x3f3f3f3f
 4 #define LL long long
 5 const int MAX=50005;
 6 int A[MAX];
 7 struct SegTree
 8 {
 9     #define M ((L+R)>>1)
10     #define lc (id<<1)
11     #define rc (id<<1|1)
12     int maxv[MAX<<2],tot;
13     void init(){memset(maxv,0,sizeof(maxv));tot=0;}
14     void push_up(int id)
15     {
16         maxv[id]=max(maxv[lc],maxv[rc]);
17     }
18     void build(int L,int R,int id)
19     {
20         if(L==R) {
21                 maxv[id]=A[++tot];
22         return; }
23         build(L,M,lc);
24         build(M+1,R,rc);
25         push_up(id);
26     }
27     int Find(int L,int R,int id,int v)
28     {
29         //cout<<L<<‘ ‘<<R<<‘ ‘<<id<<endl;
30         if(L==R) {return L;}
31         if(maxv[lc]>=v){
32             return Find(L,M,lc,v);
33         }
34         else{
35             return Find(M+1,R,rc,v);
36         }
37     }
38     void change(int L,int R,int id,int x)
39     {
40         if(L==R){maxv[id]++;return;}
41         if(x<=M) change(L,M,lc,x);
42         else change(M+1,R,rc,x);
43         push_up(id);
44     }
45 }seg;
46 int main()
47 {
48     int n,m,i,j,k,b;
49     cin>>m>>n;
50     seg.init();
51     for(i=1;i<=m;++i)
52         scanf("%d",&A[i]); A[m+1]=inf;
53     seg.build(1,m+1,1);
54     for(i=1;i<=n;++i)
55     {
56         scanf("%d",&b);
57         k=seg.Find(1,m+1,1,b);
58         if(k==1||k==m+1) continue;
59         A[k-1]++;
60         seg.change(1,m+1,1,k-1);
61     }
62     for(i=1;i<=m;++i) printf("%d\n",A[i]);
63     return 0;
64 }

 

以上是关于51nod 1287 线段树的主要内容,如果未能解决你的问题,请参考以下文章

51nod1287(二分线段树)

51NOD 1287 加农炮(不水的线段树)

51nod 1272 思维/线段树

51nod 1199 Money out of Thin Air(线段树+树剖分)

51Nod 1571 最近等对(线段树离线查询)

51Nod—1174 区间中最大的数 线段树模版