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
",A[i]);
63     return 0;
64 }
原文地址:https://www.cnblogs.com/zzqc/p/7406200.html