51nod 1287 线段树
2017-08-21 19:21
381 查看
http://www.51nod.com/onlineJudge/questionCode.html#!problemId=1287
简单的线段树题目,直接写个二分查找大于等于x的最小位置就好了。
#include<bits/stdc++.h> using namespace std; #define inf 0x3f3f3f3f #define LL long long const int MAX=50005; int A[MAX]; struct SegTree { #define M ((L+R)>>1) #define lc (id<<1) #define rc (id<<1|1) int maxv[MAX<<2],tot; void init(){memset(maxv,0,sizeof(maxv));tot=0;} void push_up(int id) { maxv[id]=max(maxv[lc],maxv[rc]); } void build(int L,int R,int id) { if(L==R) { maxv[id]=A[++tot]; return; } build(L,M,lc); build(M+1,R,rc); push_up(id); } int Find(int L,int R,int id,int v) { //cout<<L<<' '<<R<<' '<<id<<endl; if(L==R) {return L;} if(maxv[lc]>=v){ return Find(L,M,lc,v); } else{ return Find(M+1,R,rc,v); } } void change(int L,int R,int id,int x) { if(L==R){maxv[id]++;return;} if(x<=M) change(L,M,lc,x); else change(M+1,R,rc,x); push_up(id); } }seg; int main() { int n,m,i,j,k,b; cin>>m>>n; seg.init(); for(i=1;i<=m;++i) scanf("%d",&A[i]); A[m+1]=inf; seg.build(1,m+1,1); for(i=1;i<=n;++i) { scanf("%d",&b); k=seg.Find(1,m+1,1,b); if(k==1||k==m+1) continue; A[k-1]++; seg.change(1,m+1,1,k-1); } for(i=1;i<=m;++i) printf("%d\n",A[i]); return 0; }
相关文章推荐
- 51nod 1287加农炮【线段树*好题】
- 51nod - 1287 加农炮(线段树)
- 加农炮 51Nod - 1287(线段树)
- 51nod 1287 加农炮(二分/线段树)
- 51nod 1287 加农炮 【线段树】
- 51Nod 1174 区间中最大的数<线段树>
- 51nod 1206 Picture 矩形周长求并 | 线段树 扫描线
- 【51Nod】1672 - 区间交(线段树 & 贪心)
- 51nod 1364 最大字典序排列(线段树)
- 51nod-1376(线段树维护区间最值)
- HDU5828(线段树好题,区间加,区间求根号,吉老师在51nod直播讲过这道题,相应的还有区间取模)
- 51nod 1287 加农炮(分块)
- 51NOD 1210 矩阵查询 【线段树/树状数组】
- [51nod 1208] Stars in Your Window(线段树,扫描线)
- 51nod 1287 加农炮(锻炼思维的好题)
- 51nod 1376 最长递增子序列的数量(线段树)
- 51Nod 1487 思维+线段树
- 【51nod】1494 选举拉票 扫描线+线段树
- 51nod 1672 区间交【线段树】【贪心】
- 【51nod】1461 稳定桌 扫描线+线段树