51nod1287(二分、线段树)
链接:https://www.51nod.com/onlineJudge/questionCode.html#!problemId=1287
思路:二分查找大于等于b[i]的最前面的位置(想起一次错漏百出的网赛中一道没在比赛A掉的题),并更新线段树,总复杂度nlogn。
#include<bits/stdc++.h> using namespace std; typedef long long ll; const int N = 5e4 + 3; struct node { int l,r; int val; }q[N<<2]; int a[N],b[N]; void built(int l,int r,int pos) { q[pos].l = l; q[pos].r = r; if(l == r) { q[pos].val = a[l]; return; } int mid = (l + r) >> 1; built(l,mid,2*pos); built(mid+1,r,2*pos+1); q[pos].val= max(q[2*pos].val,q[2*pos+1].val); } void update(int i,int pos) { if(q[pos].l == q[pos].r) { q[pos].val++; return; } int mid = (q[pos].l + q[pos].r) >> 1; if(i > mid) update(i,2*pos+1); else update(i,2*pos); q[pos].val= max(q[2*pos].val,q[2*pos+1].val); } int get_id(int val,int pos) { if(q[pos].l == q[pos].r) { if(val > q[pos].val) return 0; return q[pos].l; } if(val > q[2*pos].val) return get_id(val,2*pos+1); else return get_id(val,2*pos); } int main() { int m,n; scanf("%d %d",&m,&n); for(int i = 1; i <= m; i++) scanf("%d",&a[i]); for(int i = 1; i <= n; i++) scanf("%d",&b[i]); built(1,m,1); for(int i = 1; i <= n; i++) { int id = get_id(b[i],1); if(id > 1) { a[id-1]++; update(id-1,1); } } for(int i = 1; i <= m; i++) printf("%d\n",a[i]); return 0; }