1. 程式人生 > >51nod 1287 線段樹

51nod 1287 線段樹

pan blank ini esp code str %d change ont

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 線段樹