"SDOI2011" divide and conquer interceptor missiles CDQ + Fenwick tree

Meaning of the questions:

A country in order to defend against enemy missile attacks, to develop a missile interception system. However, this system has an interceptor missile defective: although it is possible to reach the first rounds arbitrary height, and can be an arbitrary speed of the interceptor missile, but each out of the front shell not be higher than the height of the intercept missile flight speed can not be greater than the previous first serve. One day, the radar picked up incoming enemy missiles. As the system is still in beta, so only a system, and therefore may not intercept all the missiles.

In the case of not intercept all the missiles, of course we want to choose the country with minimal loss, which is the largest number of program to intercept missiles. But the number of interceptor missiles most likely to have multiple solutions, if there are multiple optimal solution, then we will randomly select a final interceptor missiles as a blueprint for action.

We spy has gained height and speed of all enemy missiles, your task is to calculate the probability in the implementation of the above decision, each missile was blocked off.

Input:

The first line contains a positive integer \ (n-\) , represents the number of enemy missiles;

Here \ (n \) line in order to give all the enemy missiles information:

The first \ (i + 1 \) line contains \ (2 \) positive integer \ (H_i \) and \ (V_I \) , represent the first \ (I \) altitude and velocity of the missiles.

Output:

Comprising two output lines.

The first line a positive integer representing the largest number of missiles to intercept out;

The second line contains \ (n-\) a \ (0 \) to \ (1 \) a real number between, the \ (I \) number indicates the probability of being intercepted ii missiles out (You can keep as many significant digits).

Ideas:

About the first question may be considered if the \ (dp [j] \) can be \ (dp [i] \) update, the condition has to be satisfied:
. 1, \ (I <J \)
2, \ (H_i> = h_j \)
. 3, \ (V_I> = v_J \)
there are three constraints, i.e. a three-dimensional partial ordering problem can be maintained directly CDQ, in CDQ by the \ (ID \) is divided into two sections, according to \ ( v \) to sort, and then Fenwick tree maintenance \ (h \)

Then we can consider the second question.
Each missile was intercepted probability = the number of missile programs appear / total number of programs, where the program refers to the interceptor missiles can reach most of the program.
Recording two arrays here, \ ([I] SUM \) indicating \ (dp [i] \) how many transfer method, \ (SZ [I] \) is represented by \ (I \) backward transfer there are several programs to achieve maximum transfer of many kinds.
If \ (n-\) is relatively small, it can be directly considered \ (n ^ 2 \) is calculated.

 for(int i=n; i>=1; i--) {
            if(dp[i]==ans)cnt[i]=1;
            if(dp[i]==1)sum[i]=1;
        }
        for(int j=1; j<=n; j++)
            for(int i=j+1; i<=n; i++) {
                if(dp[i]==dp[j]+1&&a[j].h>=a[i].h&&a[j].v>=a[i].v)sum[i]+=sum[j];
            }
        for(int i=1; i<=n; i++)if(dp[i]==ans)tot+=sum[i];//用来计算总的方案数
        for(int i=n; i>=1; i--)
            for(int j=i-1; j>=1; j--)
                if(dp[i]==dp[j]+1&&a[j].h>=a[i].h&&a[j].v>=a[i].v)cnt[j]+=cnt[i];

But \ (n \) is relatively large when obviously it is not alright, this time we can see three restrictions still exist, so you can proceed with the CDQ.
For \ (sum [i] \) can be directly processed in the first CDQ (since they are positive sequence) is, in the tree only remember a multiple number array, while for \ (SZ \) CDQ each first processing then becomes the right range. Back updated when there is a condition that \ (dp [j] == dp [i] +1 \) can be the maximum value of the tree into this array points to a maximum recorded take several Number then each update time only and then sentenced to about \ (dp [i] + mx \) is equal to the maximum value.

Note: The total number of programs will be open so you can tie long long double

#include<bits/stdc++.h>
#define M 50005
#define db double
#define lowbit(x) (x&-x)
using namespace std;
bool cur1;
int n,b[M],c[M],id1,id2,dp[M],ans,Dp[M];
db sum[M],sz[M];
struct node {
    int h,v,id;
    bool operator<(const node&_)const {
        if(v!=_.v)return v>_.v;
        return h>_.h;
    }
} a[M],Q[M],C[M];
struct Tree {
    int cnt[M];
    db Sum[M];
    void Init() {
        for(int i=1; i<=id1; i++)Sum[i]=cnt[i]=0;
    }
    void add(int x,int y,db v) {
        while(x) {
            if(cnt[x]<y)cnt[x]=y,Sum[x]=v;
            else if(cnt[x]==y)Sum[x]+=v;
            x-=lowbit(x);
        }
    }
    void sum(int x,int &res,db &y) {
        res=y=0;
        while(x<=id1) {
            if(res<cnt[x])res=cnt[x],y=Sum[x];
            else if(res==cnt[x])y+=Sum[x];
            x+=lowbit(x);
        }
    }
    void clear(int x) {
        while(x)cnt[x]=0,Sum[x]=0,x-=lowbit(x);
    }
    void INit() {
        for(int i=1; i<=id1; i++)Sum[i]=cnt[i]=0;
    }
    void Add(int x,int y,db v) {
        if(x==0||y==0)return;
        while(x<=id1) {
            if(cnt[x]<y)cnt[x]=y,Sum[x]=v;
            else if(cnt[x]==y)Sum[x]+=v;
            x+=lowbit(x);
        }
    }
    void get(int x,int &res,db &y) {
        res=0,y=0;
        while(x) {
            if(res<cnt[x])res=cnt[x],y=Sum[x];
            else if(res==cnt[x])y+=Sum[x];
            x-=lowbit(x);
        }
    }
    void Clear(int x) {
        while(x<=id1)cnt[x]=Sum[x]=0,x+=lowbit(x);
    }
} T;
void CDQ(int l,int r) {
    if(l>r)return;
    if(l==r) {
        dp[l]=max(dp[l],1);
        if(dp[l]==1)sum[l]=1;
        ans=max(ans,dp[l]);
        return;
    }
    int mid=(l+r)>>1;
    CDQ(l,mid);
    for(int i=l; i<=r; i++)Q[i]=a[i],Q[i].id=i;
    sort(Q+l,Q+mid+1),sort(Q+mid+1,Q+r+1);
    int x=l,y=mid+1,now=l;
    while(x<=mid&&y<=r) {
        if(Q[x].v>=Q[y].v)C[now++]=Q[x++];
        else C[now++]=Q[y++];
    }
    while(x<=mid)C[now++]=Q[x++];
    while(y<=r)C[now++]=Q[y++];
    for(int i=l; i<=r; i++) {
        if(C[i].id<=mid)T.add(C[i].h,dp[C[i].id],sum[C[i].id]);
        else {
            int res;
            db tot;
            T.sum(C[i].h,res,tot);
            res++;
            if(res>dp[C[i].id])dp[C[i].id]=res,sum[C[i].id]=tot;
            else if(res==dp[C[i].id])sum[C[i].id]+=tot;
        }
    }
    for(int i=l; i<=r; i++)if(C[i].id<=mid)T.clear(C[i].h);
    CDQ(mid+1,r);
}
void cdq(int l,int r) {
    if(l>r)return;
    if(l==r) {
        if(dp[l]==ans)sz[l]=1;
        Dp[l]=max(Dp[l],1);
        return;
    }
    int mid=(l+r)>>1;
    cdq(mid+1,r);//先处理右区间
    for(int i=l; i<=r; i++)Q[i]=a[i],Q[i].id=i;
    sort(Q+l,Q+mid+1),sort(Q+mid+1,Q+r+1);
    int x=l,y=mid+1,now=l;
    while(x<=mid&&y<=r) {
        if(Q[x].v>=Q[y].v)C[now++]=Q[x++];
        else C[now++]=Q[y++];
    }
    while(x<=mid)C[now++]=Q[x++];
    while(y<=r)C[now++]=Q[y++];
    for(int i=r; i>=l; i--) {
        if(C[i].id>mid)T.Add(C[i].h,ans-dp[C[i].id]+1,sz[C[i].id]);
        else {
            int res;
            db tot;
            T.get(C[i].h,res,tot);
            if(res+dp[C[i].id]==ans)Dp[C[i].id]=res+1,sz[C[i].id]+=tot;
        }
    }
    for(int i=l; i<=r; i++)if(C[i].id>mid)T.Clear(C[i].h);
    cdq(l,mid);
}
struct P2 {
    void solve() {
        ans=0;
        T.Init(),CDQ(1,n);
        printf("%d\n",ans);
    }
} p2;
struct P3 {
    void solve() {
        T.INit();
        db tot=0;
        cdq(1,n);
        for(int i=1; i<=n; i++)if(dp[i]==ans)tot+=sum[i];//计算总的方案
        for(int i=1; i<=n; i++) {
            printf("%.5lf",1.0*sz[i]*sum[i]/tot);
            if(i!=n)printf(" ");
            else printf("\n");
        }
    }
} p3;
bool cur2;
int main() {
//  printf("%lf\n",(&cur2-&cur1)/1024.0/1024);
//  freopen("2.in","r",stdin);
    freopen("missile.in","r",stdin);
    freopen("missile.out","w",stdout);
    scanf("%d",&n);
    for(int i=1; i<=n; i++)scanf("%d%d",&a[i].h,&a[i].v),b[++id1]=a[i].h,c[++id2]=a[i].v;
    sort(b+1,b+id1),sort(c+1,c+id2);
    id1=unique(b+1,b+id1)-b-1;
    id2=unique(c+1,c+id2)-c-1;
    for(int i=1; i<=n; i++) {
        a[i].h=lower_bound(b+1,b+id1,a[i].h)-b;
        a[i].v=lower_bound(c+1,c+id2,a[i].v)-c;
    }
    p2.solve();
    p3.solve();
    return 0;
}

Guess you like

Origin www.cnblogs.com/cly1231/p/11334050.html