zoukankan      html  css  js  c++  java
  • FJ省队集训DAY2 T2

     

    思路:我们可以考虑三角剖分,这样问题就变成考虑三角形的选取概率和三角形内有多少个点了。

    先用树状数组预处理出三角剖分的三角形中有多少个点,然后用线段树维护,先用原点极角排序,然后枚举i,再以i极角排序,此时线段树的作用就来了,每次到一个询问的教室点,我们就在线段树里面查找之前的概率,统计贡献即可。

    #include<cstdio>
    #include<iostream>
    #include<cmath>
    #include<cstring>
    #include<algorithm>
    #define MAXN 2005
    struct Point{
        double x,y;
        double p,ang;
        int id;
    }p[MAXN],Cur[MAXN];
    double P[MAXN],T[MAXN * 4];
    int n,m,rk[MAXN],s[MAXN],f[MAXN][MAXN];
    int read(){
        int t=0,f=1;char ch=getchar();
        while (ch<'0'||ch>'9'){if (ch=='-')f=-1;ch=getchar();}
        while ('0'<=ch&&ch<='9'){t=t*10+ch-'0';ch=getchar();}
        return t*f;
    }
    bool cmp(Point p1,Point p2){
        return p1.ang<p2.ang;
    }
    void build (int k,int l,int r){
        if (l==r) {T[k]=1-P[Cur[l].id];return;}
        int mid=(l+r)>>1;
        build(k*2,l,mid);
        build(k*2+1,mid+1,r);
        T[k]=T[k*2]*T[k*2+1];
    }
    double query(int k,int l,int r,int x,int y){
        if (y<l||x>r) return 1.0;
        if (x<=l&&r<=y) return T[k];
        int mid=(l+r)>>1;
        return query(k*2,l,mid,x,y)*query(k*2+1,mid+1,r,x,y);
    }
    void init(){
        n=read();m=read();
        for (int i=1;i<=n;i++)
          scanf("%lf%lf",&p[i].x,&p[i].y);
        for (int i=n+1;i<=n+m;i++)
          scanf("%lf%lf%lf",&p[i].x,&p[i].y,&P[i]);
        for (int i=1;i<=n+m;i++)
         p[i].ang=atan2(p[i].y,p[i].x);   
    }
    void add(int pos){
        for (;pos<=n+m;pos+=(pos)&(-pos)) s[pos]++;
    }
    int sum(int pos){
        int res=0;
        for (;pos;pos-=(pos)&(-pos)) res+=s[pos];
        return res;
    }
    void Sort(int mid){
        int tot=0;
        for (int i=0;i<=n+m;i++)
         if (i!=mid) Cur[++tot]=p[i],Cur[tot].ang=atan2(Cur[tot].y-p[mid].y,Cur[tot].x-p[mid].x);
        std::sort(Cur+1,Cur+1+tot,cmp);
        for (int i=1;i<=tot;i++) rk[Cur[i].id]=i;
    }
    int range(int l,int r){
        if (l<=r) return sum(r)-sum(l-1);
        return sum(n+m)-sum(l-1)+sum(r);
    }
    void solve(){
        for (int i=1;i<=n+m;i++)
         p[i].ang=atan2(p[i].y,p[i].x),p[i].id=i;
        std::sort(p+1,p+1+n+m,cmp);
        for (int i=1;i<=n+m+1;i++)
         if (p[i].id>n){
                Sort(i);
                for (int j=0;j<=n+m;j++) s[j]=0;
                for (int j=i+1;j<=n+m+1;j++){
                    if (p[j].id<=n&&p[j].id) add(rk[p[j].id]);
                    f[p[i].id][p[j].id]=std::max(0,range(rk[p[j].id],rk[0]));
                }
                for (int j=0;j<=n+m;j++) s[j]=0;
                for (int j=i-1;j;j--){
                    if (p[j].id<=n&&p[j].id) add(rk[p[j].id]);
                    f[p[i].id][p[j].id]=std::max(0,range(rk[0],rk[p[j].id])); 
                }
         }
    }
    double ask(int l,int r){
        if (l>r) return query(1,1,n+m-1,l,n+m-1)*query(1,1,n+m-1,1,r-1);
        else return query(1,1,n+m-1,l,r-1);
    }
    void linear(){
        double ans=0.0;
        int tot=0;
        for (int i=1;i<=n+m;i++)
         if (p[i].id>n){
                tot=0;
                for (int j=1;j<=n+m;j++)
                 if (i!=j) Cur[++tot]=p[j],Cur[tot].ang=atan2(p[j].y-p[i].y,p[j].x-p[i].x);
                std::sort(Cur+1,Cur+1+tot,cmp);
                build(1,1,tot);
                for (int j=1,Pp=2;j<=tot;j++){
                    for(;(Cur[j].x - p[i].x) * (Cur[Pp].y - p[i].y) - (Cur[j].y - p[i].y) * (Cur[Pp].x - p[i].x) > 0;) Pp=Pp%tot+1;
                    if (Cur[j].id>n){
                        double pr=ask(Pp,j)*P[p[i].id]*P[Cur[j].id];
                        if (p[i].x * Cur[j].y - p[i].y * Cur[j].x < 0) 
                            ans -= pr * f[p[i].id][Cur[j].id]; else
                            ans += pr * f[p[i].id][Cur[j].id];
                         }
                    }
                } 
        printf("%.9lf
    ",ans);
    }
    int main(){
        init();
        solve();
        linear();
    }
  • 相关阅读:
    移植nand驱动补缺:make mrproper与make clean以及make distclean,find/grep. makefile
    repo使用
    git使用总结
    notepade++使用
    linux内核源代码、配置与编译
    linux内核介绍
    块设备
    PHP和javascript中url编码解码详解
    python中的类方法、静态方法、对象方法
    webpack+vue中安装使用vue-layer弹窗插件
  • 原文地址:https://www.cnblogs.com/qzqzgfy/p/5641836.html
Copyright © 2011-2022 走看看