BZOJ:2244: [SDOI2011]拦截导弹

Posted ws_zzy

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了BZOJ:2244: [SDOI2011]拦截导弹相关的知识,希望对你有一定的参考价值。

问题:

  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\n",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;
}

  

以上是关于BZOJ:2244: [SDOI2011]拦截导弹的主要内容,如果未能解决你的问题,请参考以下文章

bzoj 2244: [SDOI2011]拦截导弹

[BZOJ2244][SDOI2011]拦截导弹

Bzoj2244: [SDOI2011]拦截导弹

BZOJ:2244: [SDOI2011]拦截导弹

bzoj2244: [SDOI2011]拦截导弹

bzoj千题计划292:bzoj2244: [SDOI2011]拦截导弹