zoukankan      html  css  js  c++  java
  • bzoj:3616: War

    Description

    小x所在的世界正在经历一场在k个阵营之间的战争。每个阵营有若干个炮塔,每个炮塔由攻击系统和防御系统组成。第i个炮塔可以攻击到离它欧几里德距离小于等于ri 或者曼哈顿距离小于等于ai的炮塔,被攻击到的炮塔防御系统就会崩溃,同一联盟的炮塔不会被攻击到。每次会随机选择一个炮塔攻击它能打到的所有炮塔,问进行m轮后期望剩下多少个阵营,使得这些阵营拥有的炮塔的防御系统全部完好。防御系统崩溃的炮塔还是会被打到的。值得注意的是,如果一个联盟没有任何炮塔,那么不管怎样它都是完好的。

    Input

      输入文件第一行有三个整数n、m、k,分别表示炮塔数目、攻击轮数以及联盟个数。 接下去n行每行有五个正整数xi、yi、ri、ai、pi,其中xi、yi表示炮塔坐标,p表示炮塔所属于阵营。

    Output

      输出一行一个实数表示答案,你的输出与标准输出的误差在1e-3以内会被认为是正确的。

    Sample Input

    2 2 3
    0 0 2 2 1
    1 1 2 2 2

    Sample Output

    1.500
     
     
    建完k-d树直接查找记得打标记就好了。
    然而某邻接表写炸,RE了两发,最后#8还是不错的
    从网上拷来3份标程(CA,Claris,鸟神),加上自己的AC代码共4份,随机造数据居然能出现4个不同的答案……(CA爷的代码最不和群
    #include<cmath>
    #include<bitset>
    #include<cstdio>
    #include<vector>
    #include<algorithm>
    #define ii inline int
    #define MN 36000
    #define MM 5000000
    using namespace std;
    
    int n,m,f,ro=0,num=0,xx,X,o,la=0,NO,l[MN+1],k;
    double MMH=0;
    char cs;
    ii read(){
        cs=getchar();xx=0;f=1;
        while(cs<'0'||cs>'9') {if (cs=='-') f=-1;cs=getchar();}
        while(cs>='0'&&cs<='9') xx=xx*10+cs-48,cs=getchar();
        return xx*f;
    }
    struct tr{
        int x,y,r,a;
        friend bool operator<(tr a,tr b){if (X) return a.y<b.y;else return a.x<b.x;}
        friend bool operator ==(tr a,tr b){return (a.x==b.x)&&(a.y==b.y);}
    }a[MN+1],aw;
    struct tree{
        int xa,xi,ya,yi,l,r;
    }t[MN+1];
    struct na{
        int y,ne;
    }b[MM];
    inline void in(int x,int y){
        b[++num].y=y;b[num].ne=l[x];l[x]=num;
    }
    bitset<MN+1> G[MN+1];
    vector <int> V[MN+1];
    ii S(int x){return x*x;}
    ii A(int a,int b){return a>b?a:b;}
    ii I(int a,int b){return a<b?a:b;}
    ii B(int a){return a<0?-a:a;}
    ii build(int l,int r,int now){
        X=now;
        int mid=(l+r)>>1;
        nth_element(a+l,a+mid,a+r+1);
        t[mid].xa=t[mid].xi=a[mid].x;
        t[mid].ya=t[mid].yi=a[mid].y;
        t[mid].l=t[mid].r=0;
        if (l<mid) t[mid].l=build(l,mid-1,now^1),
        t[mid].xa=A(t[t[mid].l].xa,t[mid].xa),
        t[mid].xi=I(t[t[mid].l].xi,t[mid].xi),
        t[mid].ya=A(t[t[mid].l].ya,t[mid].ya),
        t[mid].yi=I(t[t[mid].l].yi,t[mid].yi);
        if (mid<r) t[mid].r=build(mid+1,r,now^1),
        t[mid].xa=A(t[t[mid].r].xa,t[mid].xa),
        t[mid].xi=I(t[t[mid].r].xi,t[mid].xi),
        t[mid].ya=A(t[t[mid].r].ya,t[mid].ya),
        t[mid].yi=I(t[t[mid].r].yi,t[mid].yi);
        return mid;
    }
    ii gnm(int j){return A(a[NO].x-t[j].xa,0)+A(t[j].xi-a[NO].x,0)+A(a[NO].y-t[j].ya,0)+A(t[j].yi-a[NO].y,0);}
    ii gnq(int j){return S(A(a[NO].x-t[j].xa,0)+A(t[j].xi-a[NO].x,0))+S(A(a[NO].y-t[j].ya,0)+A(t[j].yi-a[NO].y,0));}
    ii gmm(int j){return A(B(a[NO].x-t[j].xa),B(a[NO].x-t[j].xi))+A(B(a[NO].y-t[j].yi),B(a[NO].y-t[j].ya));}
    ii gmq(int j){return S(A(B(a[NO].x-t[j].xa),B(a[NO].x-t[j].xi)))+S(A(B(a[NO].y-t[j].yi),B(a[NO].y-t[j].ya)));}
    ii in(int x){
        if (gmq(x)<=a[NO].r) return 1;
        if (gmm(x)<=a[NO].a) return 1;
        if (gnq(x)<=a[NO].r) return 2;
        if (gnm(x)<=a[NO].a) return 2;
        return 0;
    }
    ii ju(int x){
        if (S(a[x].x-a[NO].x)+S(a[x].y-a[NO].y)<=a[NO].r) return 1;
        if (B(a[x].x-a[NO].x)+B(a[x].y-a[NO].y)<=a[NO].a) return 1;
        return 0;
    }
    ii que(int p){
        int u=in(p);
        if (u)
        if (u==1) G[p][NO]=1;else{
            if (ju(p)) in(p,NO);
            if (t[p].l) que(t[p].l);
            if (t[p].r) que(t[p].r);
        }
    }
    inline void dw(int p){
        if (t[p].l) G[t[p].l]|=G[p],dw(t[p].l);
        if (t[p].r) G[t[p].r]|=G[p],dw(t[p].r);
        for (register int i=l[p];i;i=b[i].ne) G[p][b[i].y]=1;
    }
    int main(){
        register int i,j;
        n=read();m=read();k=read();
        for (i=1;i<=n;i++) a[i].x=read(),a[i].y=read(),a[i].r=S(read()),a[i].a=read(),V[read()].push_back(i);
        ro=build(1,n,0);
        for (NO=1;NO<=n;NO++) que(ro);
        dw(ro);
        for (i=1;i<=k;i++){
            G[0]=0;
            for (j=0;j<V[i].size();j++) G[0]|=G[V[i][j]];
            for (j=0;j<V[i].size();j++) G[0][V[i][j]]=0;
            MMH+=pow(1.0-(1.0*G[0].count()/n),m);
        }
        printf("%.6lf
    ",MMH);
    }
    200724 kb 8588 ms C++/Edit 3446 B
  • 相关阅读:
    现实世界的Windows Azure:采访圣地亚哥公共安全小组的技术经理Adrian Gonzalez
    Casablanca发布:一个用C++访问云的本地类库
    现实世界的Windows Azure:采访IDV解决方案的副总经理Scott Caulk
    Rock Paper Azure Challenge春季比赛来了!
    上海职场六大关键词完全搜集之:才市
    理解 Delphi 的类(十一) 深入类中的方法[8] 抽象方法与抽象类
    理解 Delphi 的类(十一) 深入类中的方法[10] 构造方法与析构方法
    TScreen 类 获取字体列表
    理解 Delphi 的类(十一) 深入类中的方法[9] 不能被覆盖的方法与不能被继承的类
    理解 Delphi 的类(十一) 深入类中的方法[13] 方法的调用约定
  • 原文地址:https://www.cnblogs.com/Enceladus/p/5524676.html
Copyright © 2011-2022 走看看