bzoj 2244 [SDOI2011]拦截导弹(dp+CDQ+树状数组)
2018-08-11 11:42
423 查看
传送门
[b]题解[/b]
看了半天完全没发现这东西和CDQ有什么关系……
先把原序列翻转,求起来方便
然后把每一个位置表示成$(a,b,c)$其中$a$表示位置,$b$表示高度,$c$表示速度,求有多少个位置$a,b,c$都小于它,这就是一个三维偏序问题,直接CDQ就可以解决了……
然后考虑如何求第二问,就是一个导弹所在的LIS数/总的LIS数,因为一个导弹的LIS必须包含自己,以$g[i]$表示以$i$结尾的LIS总数,不难发现有如下转移式
$$g[i]=\sum g[j] \{ (i<j,h[i]<h[j],v[i]<v[j],f[j]+1=f[i]\}$$
这个也可以用CDQ来解决,只要统计出之前最大的LIS再和$f$比较就好了(完全没想出来怎么会这么神仙……)
然后再求出以$i$为开头的LIS长度和方案数,两个相乘就是他自己的方案数了
代码好长……调了好久……
[b]题解[/b]
看了半天完全没发现这东西和CDQ有什么关系……
先把原序列翻转,求起来方便
然后把每一个位置表示成$(a,b,c)$其中$a$表示位置,$b$表示高度,$c$表示速度,求有多少个位置$a,b,c$都小于它,这就是一个三维偏序问题,直接CDQ就可以解决了……
然后考虑如何求第二问,就是一个导弹所在的LIS数/总的LIS数,因为一个导弹的LIS必须包含自己,以$g[i]$表示以$i$结尾的LIS总数,不难发现有如下转移式
$$g[i]=\sum g[j] \{ (i<j,h[i]<h[j],v[i]<v[j],f[j]+1=f[i]\}$$
这个也可以用CDQ来解决,只要统计出之前最大的LIS再和$f$比较就好了(完全没想出来怎么会这么神仙……)
然后再求出以$i$为开头的LIS长度和方案数,两个相乘就是他自己的方案数了
代码好长……调了好久……
//minamoto #include<bits/stdc++.h> using namespace std; #define getc() (p1==p2&&(p2=(p1=buf)+fread(buf,1,1<<21,stdin),p1==p2)?EOF:*p1++) char buf[1<<21],*p1=buf,*p2=buf; template<class T>inline bool cmax(T&a,const T&b){return a<b?a=b,1:0;} inline int read(){ #define num ch-'0' char ch;bool flag=0;int res; while(!isdigit(ch=getc())) (ch=='-')&&(flag=true); for(res=num;isdigit(ch=getc());res=res*10+num); (flag)&&(res=-res); #undef num return res; } const int N=50005; struct BIT{ int f;double w; BIT(){f=0,w=0;} BIT(int f,double w):f(f),w(w){} }c ; int n,st ,top=0; inline void add(int x,int f,double w){ for(int i=x;i<=n;i+=i&-i){ if(c[i].f<f){ if(c[i].f==0) st[++top]=i; c[i]=(BIT){f,w}; } else if(c[i].f==f) c[i].w+=w; } } inline BIT query(int x){ BIT res; for(int i=x;i;i-=i&-i){ if(c[i].f>res.f) res=c[i]; else if(c[i].f==res.f) res.w+=c[i].w; } return res; } struct node{ int h,v,id,t; int f[2];double g[2]; }a ,q ; int wh ,wv ,id ,rk ; inline bool cmp(int i,int j) {return a[i].h<a[j].h||(a[i].h==a[j].h&&a[i].id<a[j].id);} inline bool cmpid(const node &a,const node &b) {return a.id<b.id;} void solve(int l,int r,int t){ if(l==r){ if(a[l].f[t]<1) a[l].f[t]=a[l].g[t]=1; return; } int mid=(l+r)>>1; memcpy(q+l,a+l,sizeof(node)*(r-l+1)); int q1=l,q2=mid+1; for(int i=l;i<=r;++i){ q[i].t<=mid?a[q1++]=q[i]:a[q2++]=q[i]; } solve(l,mid,t); q1=l; for(int i=mid+1;i<=r;++i){ while(q1<=mid&&a[q1].id<a[i].id) add(a[q1].v,a[q1].f[t],a[q1].g[t]),++q1; BIT res=query(a[i].v); if(res.f==0) continue; if(res.f+1>a[i].f[t]){ a[i].f[t]=res.f+1,a[i].g[t]=res.w; } else if(res.f+1==a[i].f[t]) a[i].g[t]+=res.w; } while(top){c[st[top--]]=(BIT){0,0};} solve(mid+1,r,t); merge(a+l,a+mid+1,a+mid+1,a+r+1,q+l,cmpid); memcpy(a+l,q+l,sizeof(node)*(r-l+1)); } int th=0,tv=0; int main(){ //freopen("testdata.in","r",stdin); n=read(); for(int i=1;i<=n;++i){ wh[i]=a[i].h=read(),wv[i]=a[i].v=read(),a[i].id=i,rk[i]=i; } sort(wh+1,wh+1+n),sort(wv+1,wv+1+n); th=unique(wh+1,wh+1+n)-wh-1,tv=unique(wv+1,wv+1+n)-wv-1; for(int i=1;i<=n;++i){ a[i].h=th-(lower_bound(wh+1,wh+th+1,a[i].h)-wh)+1; a[i].v=tv-(lower_bound(wv+1,wv+tv+1,a[i].v)-wv)+1; } sort(rk+1,rk+1+n,cmp); for(int i=1;i<=n;++i) a[rk[i]].t=i; solve(1,n,0); for(int i=1;i<=n;++i){ a[i].h=th-a[i].h+1; a[i].v=tv-a[i].v+1; a[i].id=n-a[i].id+1; a[i].t=n-a[i].t+1; } reverse(a+1,a+1+n); solve(1,n,1); reverse(a+1,a+1+n); double sum=0;int ans=0; for(int i=1;i<=n;++i){ int len=a[i].f[0]+a[i].f[1]-1; cmax(ans,len); } printf("%d\n",ans); for(int i=1;i<=n;++i){ if(a[i].f[0]==ans) sum+=a[i].g[0]*a[i].g[1]; } for(int i=1;i<=n;++i){ double res=a[i].g[0]*a[i].g[1]; printf("%.5lf ",(a[i].f[0]+a[i].f[1]-1==ans)?(res/sum):0); } return 0; }
相关文章推荐
- [BZOJ2244][SDOI2011]拦截导弹(DP+CDQ分治)
- bzoj 2244 [SDOI2011]拦截导弹(DP+CDQ分治+BIT)
- Bzoj2244 [SDOI2011]拦截导弹
- [CDQ分治] BZOJ 2244 [SDOI2011]拦截导弹
- BZOJ2244 & Codevs1822 [SDOI2011]拦截导弹
- [BZOJ2244][SDOI2011]拦截导弹(dp+cdq分治)
- 【bzoj】2244: [SDOI2011]拦截导弹【cdq分治】
- [BZOJ]2244: [SDOI2011]拦截导弹 DP+CDQ分治+树状数组
- 【SDOI2011】【BZOJ2244】拦截导弹
- BZOJ 2244 [SDOI2011]拦截导弹 ——CDQ分治
- bzoj 2244: [SDOI2011]拦截导弹
- bzoj 2244: [SDOI2011]拦截导弹 cdq分治
- bzoj 2244: [SDOI2011]拦截导弹
- bzoj 2244 [SDOI2011]拦截导弹
- bzoj2244[SDOI2011]拦截导弹
- BZOJ 2244: [SDOI2011]拦截导弹 [CDQ分治 树状数组]
- BZOJ 2244 SDOI2011 拦截导弹 CDQ分治/二维树状数组
- BZOJ2244 [SDOI2011]拦截导弹 【cdq分治 + 树状数组】
- 【BZOJ2244】【SDOI2011】拦截导弹
- [BZOJ2244][SDOI2011]拦截导弹 CDQ分治