CF56E Domino Principle(BIT+dp)

显然,我们先按x排序,之后其实很容易发现答案就是从后往前遍历在i后面每个满足距离条件的j的答案再加上之间的距离,

也就是f[j]+j-i,如果枚举二维,那么就会超时,我们发现这个其实就是取max,可以用线段树维护,但是我们进一步发现,对于i和i之前的,目前还没有算出来,因此直接使用树状数组也可以维护

CF56E Domino Principle(BIT+dp)
#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

 

上一篇:《剑指offer》面试题89:房屋偷盗


下一篇:Codeforces1498 E. Two Houses