问题:
printf("%.5f ",0):为什么错了?
注意:
初始值很重要
题解:
三维偏序问题;
记录从前往后最长上升子序列长度pref,条数preg
从后往前suff,sufg
如果对于某个点pref+suff==ans-1,那么打掉它的概率 preg*sufg/tot
Wa了好多次QWQ
#include<iostream> #include<cstdio> #include<cstring> #include<algorithm> #define lowbit(x) x&(-x) using namespace std; typedef long long Lint; const int maxn=3000009; int n; int ans; double tot; int pref[maxn]; double preg[maxn]; int suff[maxn]; double sufg[maxn]; struct Missile{ int x,z,y,f; double g; }a[maxn]; int b[maxn],nn; int c[maxn]; double d[maxn]; int add(int x,int val,double q){ while(x<=nn){ if(val>c[x]){ c[x]=val; d[x]=q; }else if(val==c[x]){ d[x]+=q; } x+=lowbit(x); } } int refresh(int x){ while(x<=nn){ c[x]=d[x]=0; x+=lowbit(x); } } int querymax(int x){ int ret=0; while(x){ ret=max(ret,c[x]); x-=lowbit(x); } return ret; } double querysum(int x,int val){ double ret=0; while(x){ if(c[x]==val){ ret+=d[x]; } x-=lowbit(x); } return ret; } int cmpx(const Missile &tmp1,const Missile &tmp2){ return tmp1.x<tmp2.x; } int cmpy(const Missile &tmp1,const Missile &tmp2){ if(tmp1.y==tmp2.y)return tmp1.z<tmp2.z; else return tmp1.y<tmp2.y; } int cdq(int l,int r){ if(l==r)return 0; int mid=(l+r)>>1; cdq(l,mid); int t1=l,t2=mid+1; sort(a+l,a+mid+1,cmpy); sort(a+mid+1,a+r+1,cmpy); while(t2<=r){ while((t1<=mid)&&(a[t1].y<=a[t2].y)){ add(a[t1].z,a[t1].f,a[t1].g); ++t1; } int tmp=querymax(a[t2].z)+1; if(tmp>a[t2].f){ a[t2].f=tmp; a[t2].g=querysum(a[t2].z,tmp-1); }else if(tmp==a[t2].f){ a[t2].g+=querysum(a[t2].z,tmp-1); } ++t2; } for(int i=l;i<=mid;++i){ refresh(a[i].z); } sort(a+mid+1,a+r+1,cmpx); cdq(mid+1,r); } int work1(){ for(int i=1;i<=n;++i){ a[i].y=-a[i].y; a[i].z=nn-a[i].z+1; a[i].f=a[i].g=1; } cdq(1,n); for(int i=1;i<=n;++i){ ans=max(ans,a[i].f); pref[a[i].x]=a[i].f; preg[a[i].x]=a[i].g; } for(int i=1;i<=n;++i){ if(a[i].f==ans)tot=tot+a[i].g; } } int work2(){ for(int i=1;i<=n;++i){ a[i].x=-a[i].x; a[i].y=-a[i].y; a[i].z=nn-a[i].z+1; a[i].f=a[i].g=1; } sort(a+1,a+1+n,cmpx); cdq(1,n); for(int i=1;i<=n;++i){ suff[-a[i].x]=a[i].f; sufg[-a[i].x]=a[i].g; } } int Getans(){ printf("%d ",ans); for(int i=1;i<=n;++i){ if(pref[i]+suff[i]-1==ans){ printf("%.5f ",preg[i]*sufg[i]/tot); }else{ printf("%d ",0); } } } int minit(){ tot=0; ans=0; for(int i=0;i<=n;++i){ d[i]=c[i]=0; } } int main(){ // freopen("Misslie.in","r",stdin); // freopen("Misslie.out","w",stdout); scanf("%d",&n); minit(); for(int i=1;i<=n;++i){ scanf("%d%d",&a[i].y,&a[i].z); a[i].x=i; b[i]=a[i].z; } sort(b+1,b+1+n); nn=unique(b+1,b+1+n)-b-1; for(int i=1;i<=n;++i){ a[i].z=lower_bound(b+1,b+1+nn,a[i].z)-b; } work1(); work2(); Getans(); return 0; }