Premier Bob的算法模板库(II)

返回上一章 Premier Bob的算法模板库(I)


Geometry_Calculate_Basic .hpp (计算几何基础运算)

#include<cmath>
#include<iostream>
#include<cstdlib>
#include<cstdio>
using namespace std;

namespace Geometry_Calculate_Basic
{
    const double PI=acos(-1.0);

    struct Point{double x,y;Point(double X=0,double Y=0){x=X;y=Y;}};
    typedef Point Vector;

    Vector operator+(Vector A,Vector B){return Vector(A.x+B.x,A.y+B.y);}
    Vector operator-(Point A,Point B){return Point(A.x-B.x,A.y-B.y);}
    Vector operator*(Vector A,double p){return Vector(A.x*p,A.y*p);}
    Vector operator/(Vector A,double p){return Vector(A.x/p,A.y/p);}

    bool operator<(const Point& a, const Point& b){return a.x<b.x || (a.x==b.x && a.y<b.y);}

    const double eps=1e-10;
    int dcmp(double x){if(fabs(x)<eps)return 0;else return x<0 ? -1 : 1;}
    bool operator==(const Point& a,const Point& b){return dcmp(a.x-b.x)==0 && dcmp(a.y-b.y)==0;}

    double Dot(Vector A,Vector B){return A.x*B.x+A.y*B.y;}
    double Length(Vector A){return sqrt(Dot(A,A));}
    double Angle(Vector A,Vector B){return acos(Dot(A,B)/Length(A)/Length(B));}
    double Cross(Vector A,Vector B){return A.x*B.y-A.y*B.x;}

    double Area2(Point A,Point B,Point C){return Cross(B-A,C-A);}

    typedef double ArcAngle;
    Vector Rotate(Vector A,ArcAngle rad){return Vector(A.x*cos(rad)-A.y*sin(rad),A.x*sin(rad)+A.y*cos(rad));}
    Vector Normal(Vector A){double L=Length(A);return Vector(-A.y/L,A.x/L);}

    Point GetLineIntersection(Point P,Vector v,Point Q,Vector w)
    {
        Vector u=P-Q;
        double t=Cross(w,u)/Cross(v,w);
        return P+v*t;
    }

    double DistanceToLine(Point P,Point A,Point B)
    {
        Vector v1=B-A,v2=P-A;
        return fabs(Cross(v1,v2))/Length(v1);
    }

    double DistanceToSegment(Point P,Point A,Point B)
    {
        if(A==B)
            return Length(P-A);
        Vector v1=B-A,v2=P-A,v3=P-B;
        if(dcmp(Dot(v1,v2))<0)return Length(v2);
        else if(dcmp(Dot(v1,v3))>0)
            return Length(v3);
        else return fabs(Cross(v1,v2))/Length(v1);
    }

    Point GetLineProjection(Point P,Point A,Point B)
    {
        Vector v=B-A;
        return A+v*(Dot(v,P-A)/Dot(v,v));
    }

    bool SegmentProperIntersection(Point a1,Point a2,Point b1,Point b2)
    {
        double c1=Cross(a2-a1,b1-a1),c2=Cross(a2-a1,b2-a1),
            c3=Cross(b2-b1,a1-b1),c4=Cross(b2-b1,a2-b1);
        return dcmp(c1)*dcmp(c2)<0 && dcmp(c3)*dcmp(c4)<0;
    }

    double PolygonArea(Point* p,int n)
    {
        double area=0;
        for(int i=1;i<n-1;i++)
            area+=Cross(p[i]-p[0],p[i+1]-p[0]);
        return area/2;
    }
}

但愿这个不是使用样例:

#include"Geometry_Calculate_Basic.hpp"
int main()
{
    int T;cin>>T;
    for(int i=1;i<=T;i++)
    {
        Geometry_Calculate_Basic::Point A,B,C;
        cin>>A.x>>A.y>>B.x>>B.y>>C.x>>C.y;
        Geometry_Calculate_Basic::ArcAngle c_a=Geometry_Calculate_Basic::Angle(A-B,C-B);
        Geometry_Calculate_Basic::ArcAngle a_b=Geometry_Calculate_Basic::Angle(B-C,A-C);
        Geometry_Calculate_Basic::ArcAngle b_c=Geometry_Calculate_Basic::Angle(C-A,A-B);
        Geometry_Calculate_Basic::Vector a1,a2,b1,b2,c1,c2;
        a1=Geometry_Calculate_Basic::Rotate(C-A,b_c/3*2);
        a2=Geometry_Calculate_Basic::Rotate(C-A,b_c/3);

        b1=Geometry_Calculate_Basic::Rotate(A-B,c_a/3*2);
        b2=Geometry_Calculate_Basic::Rotate(A-B,c_a/3);

        c1=Geometry_Calculate_Basic::Rotate(B-C,a_b/3*2);
        c2=Geometry_Calculate_Basic::Rotate(B-C,a_b/3);

        Geometry_Calculate_Basic::Point D,E,F;

        D=Geometry_Calculate_Basic::GetLineIntersection(B,b1,C,c2);
        E=Geometry_Calculate_Basic::GetLineIntersection(A,a1,B,b2);
        F=Geometry_Calculate_Basic::GetLineIntersection(C,c1,A,a2);

        cout<<D.x<<" "<<D.y<<" "<<E.x<<" "<<E.y<<" "<<F.x<<" "<<F.y<<endl;
    }
    return 0;
}

所以说应该写成这样:

#include"Geometry_Calculate_Basic.hpp"
using namespace Geometry_Calculate_Basic;
//using namespace!
int main()
{
    int T;cin>>T;
    for(int i=1;i<=T;i++)
    {
        Point A,B,C;
        cin>>A.x>>A.y>>B.x>>B.y>>C.x>>C.y;
        ArcAngle c_a=Angle(A-B,C-B);
        ArcAngle a_b=Angle(B-C,A-C);
        ArcAngle b_c=Angle(C-A,A-B);
        Vector a1,a2,b1,b2,c1,c2;
        a1=Rotate(C-A,b_c/3*2);
        a2=Rotate(C-A,b_c/3);

        b1=Rotate(A-B,c_a/3*2);
        b2=Rotate(A-B,c_a/3);

        c1=Rotate(B-C,a_b/3*2);
        c2=Rotate(B-C,a_b/3);

        Point D,E,F;

        D=GetLineIntersection(B,b1,C,c2);
        E=GetLineIntersection(A,a1,B,b2);
        F=GetLineIntersection(C,c1,A,a2);

        cout<<D.x<<" "<<D.y<<" "<<E.x<<" "<<E.y<<" "<<F.x<<" "<<F.y<<endl;
    }
    return 0;
}

NlogN_LIS .hpp (nlogn时间复杂度求解LIS长度)

#include<algorithm>
using namespace std;

namespace NlogN_LIS
{
    const int INF=2147483647;
    const int maxn=1048576;
    int g[maxn],d[maxn];
    int LIS(int* Array,int n)
    {
        for(int i=1;i<=n;i++)
            g[i]=INF;
        int ans=0;
        for(int i=1;i<=n;i++)
        {
            int k=lower_bound(g+1,g+n+1,Array[i])-g;
            d[i]=k;
            g[k]=Array[i];
            ans=max(ans,d[i]);
        }
        return ans;
    }
}

UnionFindSet .hpp (并查集模板)

//made by GGN -from NECY
#pragma once

#include<cstdio>
#include<cstdlib>

namespace UnionFindSet
{
    const int UFS_Size=1048576;
    //you can use this to change the size of UFS
    class UFS
    {
        int Father[UFS_Size];
        bool NeedInit;
        int UseSize;

        public:
            UFS(){NeedInit=1;}

            void Init(int NodeCount)
            {
                NeedInit=0;
                for(int i=1;i<=NodeCount;i++)
                    Father[i]=i;
                UseSize=NodeCount;
            }

            int Find(int NodeNum)
            {
                if(NeedInit)
                {
                    printf("Error \"UnionFindSet\":Find  you have to init before use!\n");
                    system("pause>nul");
                    return -1;
                }
                if(NodeNum<=0 || NodeNum>UseSize)
                {
                    printf("Error \"UnionFindSet\":Find NodeNum=%d (<=0 or >UseSize=%d) is not allowed!\n",NodeNum,UseSize);
                    system("pause>nul");
                    return -1;
                }
                if(NodeNum!=Father[NodeNum])
                    Father[NodeNum]=Find(Father[NodeNum]);
                return Father[NodeNum];
            }

            int Union(int NodeX,int NodeY)
            {
                if(NeedInit)
                {
                    printf("Error \"UnionFindSet\":Union  you have to init before use!\n");
                    system("pause>nul");
                    return -1;
                }
                if(NodeX<=0 || NodeX>UseSize)
                {
                    printf("Error \"UnionFindSet\":Union NodeX=%d (<=0 or >UseSize=%d) is not allowed!\n",NodeX,UseSize);
                    system("pause>nul");
                    return -1;
                }
                if(NodeY<=0 || NodeY>UseSize)
                {
                    printf("Error \"UnionFindSet\":Union NodeY=%d (<=0 or >UseSize=%d) is not allowed!\n",NodeY,UseSize);
                    system("pause>nul");
                    return -1;
                }
                Father[Find(NodeY)]=Find(NodeX);
            }

            int Judge(int NodeX,int NodeY)
            {
                if(NeedInit)
                {
                    printf("Error \"UnionFindSet\":Judge  you have to init before use!\n");
                    system("pause>nul");
                    return -1;
                }
                if(NodeX<=0 || NodeX>UseSize)
                {
                    printf("Error \"UnionFindSet\":Judge NodeX=%d (<=0 or >UseSize=%d) is not allowed!\n",NodeX,UseSize);
                    system("pause>nul");
                    return -1;
                }
                if(NodeY<=0 || NodeY>UseSize)
                {
                    printf("Error \"UnionFindSet\":Judge NodeY=%d (<=0 or >UseSize=%d) is not allowed!\n",NodeY,UseSize);
                    system("pause>nul");
                    return -1;
                }
                return Find(NodeX)==Find(NodeY);
            }

            int Ancestor(int Node)
            {
                if(NeedInit)
                {
                    printf("Error \"UnionFindSet\":Ancestor  you have to init before use!\n");
                    system("pause>nul");
                    return -1;
                }
                if(Node<=0 || Node>UseSize)
                {
                    printf("Error \"UnionFindSet\":Ancestor Node=%d (<=0 or >UseSize=%d) is not allowed!\n",Node,UseSize);
                    system("pause>nul");
                    return -1;
                }
                return Father[Node];
            }
    };
}

TernarySearch .hpp (三分法求单峰函数最小值)

//made by GGN -from NEYC
#pragma once

#include<cstdio>
#include<cstdlib>
#include<cmath>
namespace TernarySearch
{
    double TSmin(double L,double R,double (*function)(double x),double eps=1e-7)
    {
        //make a ternary search for min value and return x
        if(R==L)
            return L;
        if(R<L)
        {
            printf("Error \"Ternary Search\":TSmin R=%d (<L=%d) is not allowed!\n",R,L);
            system("pause>nul");
            return L;
        }
        if(function==NULL)
        {
            printf("Error \"Ternary Search\":TSmin f=[NULL] is not allowed!\n");
            system("pause>nul");
            return L;
        }
        while(fabs(L-R)>eps)
        {
            double m1=L+(R-L)/3;
            double m2=R-(R-L)/3;
            if(function(m1)<function(m2))
                R=m2;
            else
                L=m1;
        }
        return L;
    }

    double TSmax(double L,double R,double (*function)(double x),double eps=1e-7)
    {
        //make a ternary search for max value and return x
        if(R==L)
            return L;
        if(R<L)
        {
            printf("Error \"Ternary Search\":TSmin R=%d (<L=%d) is not allowed!\n",R,L);
            system("pause>nul");
            return L;
        }
        if(function==NULL)
        {
            printf("Error \"Ternary Search\":TSmin f=[NULL] is not allowed!\n");
            system("pause>nul");
            return L;
        }
        while(fabs(L-R)>eps)
        {
            double m1=L+(R-L)/3;
            double m2=R-(R-L)/3;
            if(function(m1)>function(m2))
                R=m2;
            else
                L=m1;
        }
        return L;
    }
}

Treap的基本板子

详见 Treap树堆的基本模板(无讲解)


后记

算法模板库仍在扩充中…

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值