显然,我们先按x排序,之后其实很容易发现答案就是从后往前遍历在i后面每个满足距离条件的j的答案再加上之间的距离,
也就是f[j]+j-i,如果枚举二维,那么就会超时,我们发现这个其实就是取max,可以用线段树维护,但是我们进一步发现,对于i和i之前的,目前还没有算出来,因此直接使用树状数组也可以维护
#include<bits/stdc++.h> using namespace std; typedef long long ll; typedef pair<int,int> pll; typedef pair<int,pll> plll; const int N=2e5+10; struct node{ ll cnt; ll h; int id; }s[N]; ll ans[N]; int tr[N]; int f[N]; vector<int> num; bool cmp(node a,node b){ return a.cnt<b.cnt; } int lowbit(int x){ return x&-x; } void add(int x,int c){ int i; for(i=x;i<N;i+=lowbit(i)){ tr[i]=max(tr[i],c); } } int sum(int x){ int ans=0; for(int i=x;i;i-=lowbit(i)){ ans=max(ans,tr[i]); } return ans; } int main(){ ios::sync_with_stdio(false); int n; cin>>n; int i; for(i=1;i<=n;i++){ cin>>s[i].cnt>>s[i].h; s[i].id=i; num.push_back(s[i].cnt); } sort(s+1,s+1+n,cmp); sort(num.begin(),num.end()); num.erase(unique(num.begin(),num.end()),num.end()); for(i=n;i>=1;i--){ int pos; pos=upper_bound(num.begin(),num.end(),s[i].cnt+s[i].h-1)-num.begin(); f[i]=max(sum(pos)-i,1); ans[s[i].id]=f[i]; pos=lower_bound(num.begin(),num.end(),s[i].cnt)-num.begin()+1; add(pos,f[i]+i); } for(i=1;i<=n;i++) cout<<ans[i]<<" "; cout<<endl; return 0; }View Code