P2487 [SDOI2011] interceptor missiles segment tree cdq partition

  

 

 

If he is merely seeking a two-dimensional non-liter longest sequence length that is a template cdq title dp what you can

But this problem requires not only the number of programs dp dp also requires the

Therefore, with the segment tree interval maximum value to maintain the number and interval maximum value

Initialization, then build a faster (when maxx [pos] == 0 without recursion can continue) 

 

 

 f2 g2 reverse

Then when    

f1 [i] + f2 [i] -1! = maxxans element is not apparent that any of the longest sub-sequence
Otherwise, the answer to where the program number / total number of programs g1 [i] * g2 [i] / sum
// luogu-judger-enable-o2
#include<bits/stdc++.h>
using namespace std;
#define rep(i,a,b) for(int i=(a);i<=(b);i++)
#define repp(i,a,b) for(int i=(a);i>=(b);--i)
#define ll long long
#define see(x) (cerr<<(#x)<<'='<<(x)<<endl)
#define inf 0x3f3f3f3f
#define CLR(A,v)  memset(A,v,sizeof A)
/////////////////////////////////////
const int N=1e6+10;
ll maxx[N<<2];
double t[N<<2];
int n,m,anss[N],f1[N],f2[N],xx[N],yy[N];
double g1[N],g2[N];
void build(int l,int r,int pos)
{
    if(!maxx[pos])return ;//这条加速非常重要
    maxx[pos]=t[pos]=0;
    if(l==r){maxx[pos]=t[pos]=0;return ;}
    int m=(l+r)>>1;maxx[pos]=t[pos]=0;
    build(l,m,pos<<1);build(m+1,r,pos<<1|1);
}
void up(int pos)
{
    if(maxx[pos<<1]<maxx[pos<<1|1])
    maxx[pos]=maxx[pos<<1|1],t[pos]=t[pos<<1|1];
    else if(maxx[pos<<1]>maxx[pos<<1|1])
    maxx[pos]=maxx[pos<<1],t[pos]=t[pos<<1];
    else maxx[pos]=maxx[pos<<1],t[pos]=t[pos<<1]+t[pos<<1|1];
}
void upnode(int x,int v,double v2,int l,int r,int pos)
{
    if(l==r)
    {
        if(v==maxx[pos])t[pos]+=v2;
        else if(v>maxx[pos])maxx[pos]=v,t[pos]=v2;
        return ;
    }
    int m=(l+r)>>1;
    if(x<=m)upnode(x,v,v2,l,m,pos<<1);
    else upnode(x,v,v2,m+1,r,pos<<1|1);
    up(pos);
}
ll qmax(int L,int R,int l,int r,int pos)
{
    if(L<=l&&r<=R)return maxx[pos];
    ll ans=0;int m=(l+r)>>1;
    if(L<=m)ans=max(ans,qmax(L,R,l,m,pos<<1));
    if(R>m)ans=max(ans,qmax(L,R,m+1,r,pos<<1|1));
    return ans;
}
double qnum(int L,int R,ll v,int l,int r,int pos)
{  
    if(L<=l&&r<=R){if(maxx[pos]==v)return t[pos];return 0; }
    int m=(l+r)>>1;double ans=0;
    if(L<=m)ans+=qnum(L,R,v,l,m,pos<<1);
    if(R>m)ans+=qnum(L,R,v,m+1,r,pos<<1|1);
    return ans;
}
struct node{int x,y,id;}s[N],temp[N];
bool cmp(node a,node b){return a.x<b.x;}

void cdq1(int l,int r)
{   
    if(l==r)return ;int mid=(l+r)>>1;
    cdq1(mid+1,r);
    rep(i,l,r)temp[i]=s[i];
    sort(temp+l,temp+mid+1,cmp);sort(temp+mid+1,temp+r+1,cmp);
    int j=mid+1;
    build(1,n,1);
    rep(i,l,mid)
    {   
        while(j<=r&&temp[j].x<=temp[i].x)upnode(temp[j].y,f1[temp[j].id],g1[temp[j].id],1,n,1),j++;
        double cn=0;
        ll t=qmax(1,temp[i].y,1,n,1);
        if(!t)continue;
        cn=qnum(1,temp[i].y,t,1,n,1);
        if(f1[temp[i].id]<t+1)f1[temp[i].id]=t+1,g1[temp[i].id]=0;
        if(f1[temp[i].id]==t+1)g1[temp[i].id]+=cn;
    }
    cdq1(l,mid);
}
void cdq2(int l,int r)
{   
    if(l==r)return ;int mid=(l+r)>>1;
    cdq2(l,mid);
    rep(i,l,r)temp[i]=s[i];
    sort(temp+l,temp+mid+1,cmp);sort(temp+mid+1,temp+r+1,cmp);
    int j=mid;
    build(1,n,1);
    repp(i,r,mid+1)
    {
        while(j>=l&&temp[j].x>=temp[i].x)upnode(temp[j].y,f2[temp[j].id],g2[temp[j].id],1,n,1),j--;
        double cn=0;
        ll t=qmax(temp[i].y,n,1,n,1);
        if(!t)continue;
        cn=qnum(temp[i].y,n,t,1,n,1);
        if(f2[temp[i].id]<t+1)f2[temp[i].id]=t+1,g2[temp[i].id]=0;
        if(f2[temp[i].id]==t+1)g2[temp[i].id]+=cn;
    }
    cdq2(mid+1,r);
}
int main()
{
    cin>>n;
    rep(i,1,n)scanf("%d%d",&s[i].x,&s[i].y),s[i].id=i,f1[i]=f2[i]=1,xx[i]=s[i].x,yy[i]=s[i].y,g1[i]=g2[i]=1;
    sort(xx+1,xx+1+n);sort(yy+1,yy+1+n);
    int nx=unique(xx+1,xx+1+n)-xx-1;
    int ny=unique(yy+1,yy+1+n)-yy-1;
    rep(i,1,n)
    s[i].x=lower_bound(xx+1,xx+1+nx,s[i].x)-xx,
    s[i].y=lower_bound(yy+1,yy+1+ny,s[i].y)-yy;
    cdq1(1,n);
    int maxxans=0;
    double sum=0;
    rep(i,1,n)maxxans=max(maxxans,f1[i]);
    cout<<maxxans<<endl;
    rep(i,1,n)
    if(f1[i]==maxxans)sum+=g1[i];
    sort(s+1,s+1+n,[](node a,node b){return a.id<b.id;});
    cdq2(1,n);
    rep(i,1,n)
    {
        if(f1[i]+f2[i]-1!=maxxans)printf("0.00000 ");
        else printf("%.5lf ",g1[i]*g2[i]/sum);
    }
    return 0;
}
View Code

 

Guess you like

Origin www.cnblogs.com/bxd123/p/11464810.html