bzoj2244: [SDOI2011]拦截导弹
我tmd的连三维偏序都不会写了。。
我tmd已经是个废宸了。。
似乎decdq分治的bug永远是我的痛。。
三维偏序,三维倒过来再跑一遍,看一个点前后加起来是否等于答案。
算方案用了线段树,跑得贼慢。优秀的人都会用树状数组,不会。
//Achen
#include<algorithm>
#include<iostream>
#include<cstring>
#include<cstdlib>
#include<cstdio>
#include<vector>
#include<queue>
#include<ctime>
#include<cmath>
const int N=5e4+7;
typedef long long LL;
using namespace std;
int n,ls[N],sz,f[N],ff[N],mxans;
double g[N],ans[N],gg[N];
template<typename T> void read(T &x) {
char ch=getchar(); x=0; T f=1;
while(ch!='-'&&(ch<'0'||ch>'9')) ch=getchar();
if(ch=='-') f=-1,ch=getchar();
for(;ch>='0'&&ch<='9';ch=getchar()) x=x*10+ch-'0'; x*=f;
}
struct node {
int x,y,ti,id;
}p[N];
bool CMP(const node&A,const node&B) {
return A.ti<B.ti;
}
bool cmp(const node &A,const node&B) {
return A.x>B.x||(A.x==B.x&&(A.y>B.y||(A.y==B.y&&A.ti<B.ti)));
}
#define lc x<<1
#define rc x<<1|1
#define mid ((l+r)>>1)
int mx[N<<2];
double sum[N<<2];
void update(int x,int l,int r,int pos,int fi,double gi) {
if(l==r) {
if(mx[x]<fi) sum[x]=gi,mx[x]=fi;
else if(mx[x]==fi) sum[x]+=gi; return;
}
if(pos<=mid) update(lc,l,mid,pos,fi,gi);
else update(rc,mid+1,r,pos,fi,gi);
mx[x]=max(mx[lc],mx[rc]);
if(mx[lc]==mx[rc]) sum[x]=sum[lc]+sum[rc];
else sum[x]=mx[lc]>mx[rc]?sum[lc]:sum[rc];
}
void qry(int x,int l,int r,int ql,int qr,int &f,double &g) {
if(l>=ql&&r<=qr) {
if(mx[x]+1>f) f=mx[x]+1,g=sum[x];
else if(mx[x]+1==f) g+=sum[x]; return;
}
if(ql<=mid) qry(lc,l,mid,ql,qr,f,g);
if(qr>mid) qry(rc,mid+1,r,ql,qr,f,g);
}
void clear_sg(int x,int l,int r) {
if(!mx[x]) return;
mx[x]=sum[x]=0;
clear_sg(lc,l,mid); clear_sg(rc,mid+1,r);
}
void cdq(int l,int r,int f[],double g[]) {
if(l>=r) return;
cdq(l,mid,f,g);
sort(p+l,p+r+1,cmp);
for(int i=l;i<=r;i++) {
if(p[i].ti<=mid) update(1,1,sz,p[i].y,f[p[i].id],g[p[i].id]);
else qry(1,1,sz,p[i].y,sz,f[p[i].id],g[p[i].id]);
} clear_sg(1,1,sz);
sort(p+l,p+r+1,CMP);
cdq(mid+1,r,f,g);
}
int main() {
read(n);
for(int i=1;i<=n;i++) {
read(p[i].x); read(p[i].y);
p[i].ti=p[i].id=i;
ls[++ls[0]]=p[i].y;
f[i]=g[i]=ff[i]=gg[i]=1;
}
sort(ls+1,ls+ls[0]+1);
sz=unique(ls+1,ls+ls[0]+1)-(ls+1);
for(int i=1;i<=n;i++)
p[i].y=lower_bound(ls+1,ls+sz+1,p[i].y)-ls;
cdq(1,n,f,g);
double ss=0;
for(int i=1;i<=n;i++) {
if(f[i]==mxans) ss+=g[i];
else if(f[i]>mxans) ss=g[i],mxans=f[i];
}
printf("%d\n",mxans);
for(int i=1;i<=n;i++) {
p[i].x=1e9-p[i].x+1;
p[i].y=sz-p[i].y+1;
p[i].ti=n-p[i].ti+1;
}
sort(p+1,p+n+1,CMP);
cdq(1,n,ff,gg);
for(int i=1;i<=n;i++) {
int x=p[i].id;
if(f[x]+ff[x]-1==mxans) ans[x]=g[x]*gg[x];
else ans[x]=0;
}
for(int i=1;i<=n;i++) printf("%.5lf ",ans[i]/ss);
return 0;
}
/*
4
3 30
4 40
6 60
3 30
*/