模板整理 慢慢更新

数论

矩阵快速幂

斐波那契第n项和

#include <bits/stdc++.h>
using namespace std;
#define ne 2
#define INF 1000000009

struct node
{
    long long a[ne][ne];
};

node mult(node a, node b)
{
    node c = {0};
    for(long long i = 0; i < ne; i++)
    for(long long j = 0; j < ne; j++)
    for(long long k = 0; k < ne; k++)
    {
        c.a[i][j] += (a.a[i][k] * b.a[k][j]) % INF;
        c.a[i][j] %= INF;
    }
    return c;
}
node slove(node x,long long n)
{
    node a=x;
    while(n)
    {
        if(n&1) a=mult(a,x);
        x=mult(x,x);
        n>>=1;
    }
    return a;
}
node input(long long n)
{
    node x={0};
    x.a[0][0]=1;
    x.a[0][1]=1;
    x.a[1][0]=1;
    x.a[1][1]=0;
    x=slove(x,n);
    return x;
}

int main()
{
    long long n;
    while(cin>>n)
    {
        node x=input(n);
        cout<<x.a[1][1]<<endl;
    }
}

乘法逆元

#include <bits/stdc++.h>
using namespace std;
int exgcd(int a,int b,int &x,int &y) 
{
    if (b==0)
    {
        x=1,y=0;
        return a;
    }
    int q=exgcd(b,a%b,y,x);
    y-=a/b*x;
    return q;
}

int main()
{
    int a,b,x,y;
    cin>>a>>b;
    exgcd(a,b,x,y);
    if(x<0) x+=b;
    cout<<x<<endl;
}

凸包

安德鲁算法 
安德鲁算法判断凸包需要用到叉积 
关于叉积


首先在二维坐标下介绍一些定义:
点:A(x1,y1),B(x2,y2)

向量:向量AB=( x2 - x1 , y2 - y1 )= ( x ,  y );

向量的模 |AB| = sqrt ( x*x+y*y );



向量的点积: 结果为 x1*x2 + y1*y2。

点积的结果是一个数值。

点积的集合意义:我们以向量 a 向向量 b 做垂线,则 | a | * cos(a,b)为 a 在向量 b 上的投影,即点积是一个向量在另一个向量上的投影乘以另一个向量。且满足交换律

应用:可以根据集合意义求两向量的夹角,
cos(a,b) =( 向量a * 向量b ) / (| a | * | b |) =  x1*x2 + y1*y2 / (| a | * | b |)



向量的叉积: 结果为 x1*y2-x2*y1

叉积的结果也是一个向量,是垂直于向量a,b所形成的平面,如果看成三维坐标的话是在 z 轴上,上面结果是它的模。

方向判定:右手定则,(右手半握,大拇指垂直向上,四指右向量a握向b,大拇指的方向就是叉积的方向)

叉积的集合意义:1:其结果是a和b为相邻边形成平行四边形的面积。

2:结果有正有负,有sin(a,b)可知和其夹角有关,夹角大于180°为负值。

3:叉积不满足交换律

应用:

1:通过结果的正负判断两矢量之间的顺逆时针关系

若 a x b > 0表示a在b的顺时针方向上

若 a x b < 0表示a在b的逆时针方向上

若 a x b == 0表示a在b共线,但不确定方向是否相同

在顺时针方向上为凸包 
否则是凹进去的。 
以此依次加点。 
将坐标按照x从小到大排序。 
先加上面的凸包 然后加下面的凸包。

凸包
#include <bits/stdc++.h>
using namespace std;
#define mo 100005
struct node
{
    int x,y;
}d[mo],p[mo];

int chaji(node a,node b,node c)//叉积计算
{
    return ((b.x-a.x)*(c.y-a.y)-(b.y-a.y)*(c.x-a.x));
}


bool cmp(node a,node b)//坐标点排序
{
    if(a.y!=b.y)return a.y<b.y;
    return a.x<b.x;
}
void run(int n)
{
    sort(d,d+n,cmp);
    int tot=0;
    for(int i=0;i<n;i++)
    {
        while(tot>1&&chaji(p[tot-2],p[tot-1],d[i])<0) tot--;
        p[tot++]=d[i];
    }

    for(int i=n-2;i>=0;i--)
    {
        while(tot>1&&chaji(p[tot-2],p[tot-1],d[i])<0) tot--;
        p[tot++]=d[i];
    }
    cout<<tot-1<<endl;
    for(int i=0;i<tot-1;i++)
    {
        cout<<p[i].x<<' '<<p[i].y<<endl;
    }

}

int main()
{
    int n;
    while(cin>>n)
    {
        for(int i=0;i<n;i++)
            cin>>d[i].x>>d[i].y;

        run(n);
    }



}

计算几何

多边形面积交

#include<cstdio>  
#include<iostream>  
#include<algorithm>  
#include<cstring>  
#include<cmath>  
using namespace std;  
#define maxn 510  
const double eps=1E-8;  
int sig(double d){  
    return(d>eps)-(d<-eps);  
}  
struct Point{  
    double x,y; Point(){}  
    Point(double x,double y):x(x),y(y){}  
    bool operator==(const Point&p)const{  
        return sig(x-p.x)==0&&sig(y-p.y)==0;  
    }  
};  
double cross(Point o,Point a,Point b){  
    return(a.x-o.x)*(b.y-o.y)-(b.x-o.x)*(a.y-o.y);  
}  
double area(Point* ps,int n){  
    ps[n]=ps[0];  
    double res=0;  
    for(int i=0;i<n;i++){  
        res+=ps[i].x*ps[i+1].y-ps[i].y*ps[i+1].x;  
    }  
    return res/2.0;  
}  
int lineCross(Point a,Point b,Point c,Point d,Point&p){  
    double s1,s2;  
    s1=cross(a,b,c);  
    s2=cross(a,b,d);  
    if(sig(s1)==0&&sig(s2)==0) return 2;  
    if(sig(s2-s1)==0) return 0;  
    p.x=(c.x*s2-d.x*s1)/(s2-s1);  
    p.y=(c.y*s2-d.y*s1)/(s2-s1);  
    return 1;  
}  
//多边形切割  
//用直线ab切割多边形p,切割后的在向量(a,b)的左侧,并原地保存切割结果  
//如果退化为一个点,也会返回去,此时n为1  
void polygon_cut(Point*p,int&n,Point a,Point b){  
    static Point pp[maxn];  
    int m=0;p[n]=p[0];  
    for(int i=0;i<n;i++){  
        if(sig(cross(a,b,p[i]))>0) pp[m++]=p[i];  
        if(sig(cross(a,b,p[i]))!=sig(cross(a,b,p[i+1])))  
            lineCross(a,b,p[i],p[i+1],pp[m++]);  
    }  
    n=0;  
    for(int i=0;i<m;i++)  
        if(!i||!(pp[i]==pp[i-1]))  
            p[n++]=pp[i];  
    while(n>1&&p[n-1]==p[0])n--;  
}  
//---------------华丽的分隔线-----------------//  
//返回三角形oab和三角形ocd的有向交面积,o是原点//  
double intersectArea(Point a,Point b,Point c,Point d){  
    Point o(0,0);  
    int s1=sig(cross(o,a,b));  
    int s2=sig(cross(o,c,d));  
    if(s1==0||s2==0)return 0.0;//退化,面积为0  
    if(s1==-1) swap(a,b);  
    if(s2==-1) swap(c,d);  
    Point p[10]={o,a,b};  
    int n=3;  
    polygon_cut(p,n,o,c);  
    polygon_cut(p,n,c,d);  
    polygon_cut(p,n,d,o);  
    double res=fabs(area(p,n));  
    if(s1*s2==-1) res=-res;return res;  
}  
//求两多边形的交面积  
double intersectArea(Point*ps1,int n1,Point*ps2,int n2){  
    if(area(ps1,n1)<0) reverse(ps1,ps1+n1);  
    if(area(ps2,n2)<0) reverse(ps2,ps2+n2);  
    ps1[n1]=ps1[0];  
    ps2[n2]=ps2[0];  
    double res=0;  
    for(int i=0;i<n1;i++){  
        for(int j=0;j<n2;j++){  
            res+=intersectArea(ps1[i],ps1[i+1],ps2[j],ps2[j+1]);  
        }  
    }  
    return res;//assumeresispositive!  
}  
//hdu-3060求两个任意简单多边形的并面积  
Point ps1[maxn],ps2[maxn];  
int n1,n2;  
int main(){  
    while(scanf("%d%d",&n1,&n2)!=EOF){  
        for(int i=0;i<n1;i++)  
            scanf("%lf%lf",&ps1[i].x,&ps1[i].y);  
        for(int i=0;i<n2;i++)  
            scanf("%lf%lf",&ps2[i].x,&ps2[i].y);  
        double ans=intersectArea(ps1,n1,ps2,n2);  
        ans=fabs(area(ps1,n1))+fabs(area(ps2,n2))-ans;//容斥  
        printf("%.2f\n",ans);  
    }  
    return 0;  
}  

多边形面积交

#include<cstdio>
#include<cmath>
#include<cstring>
#include<iostream>
#include<algorithm>
#include<cstdlib>
#include<queue>
#include<map>
#include<stack>
#include<set>

using namespace std;

const int maxn=555;
const int maxisn=10;
const double eps=1e-8;
const double pi=acos(-1.0);

int dcmp(double x){
    if(x>eps) return 1;
    return x<-eps ? -1 : 0;
}
inline double Sqr(double x){
    return x*x;
}
struct Point{
    double x,y;
    Point(){x=y=0;}
    Point(double x,double y):x(x),y(y){};
    friend Point operator + (const Point &a,const Point &b) {
        return Point(a.x+b.x,a.y+b.y);
    }
    friend Point operator - (const Point &a,const Point &b) {
        return Point(a.x-b.x,a.y-b.y);
    }
    friend bool operator == (const Point &a,const Point &b) {
        return dcmp(a.x-b.x)==0&&dcmp(a.y-b.y)==0;
    }
    friend Point operator * (const Point &a,const double &b) {
        return Point(a.x*b,a.y*b);
    }
    friend Point operator * (const double &a,const Point &b) {
        return Point(a*b.x,a*b.y);
    }
    friend Point operator / (const Point &a,const double &b) {
        return Point(a.x/b,a.y/b);
    }
    friend bool operator < (const Point &a, const Point &b) {
        return a.x < b.x || (a.x == b.x && a.y < b.y);
    }
    inline double dot(const Point &b)const{
        return x*b.x+y*b.y;
    }
    inline double cross(const Point &b,const Point &c)const{
        return (b.x-x)*(c.y-y)-(c.x-x)*(b.y-y);
    }

};

Point LineCross(const Point &a,const Point &b,const Point &c,const Point &d){
    double u=a.cross(b,c),v=b.cross(a,d);
    return Point((c.x*v+d.x*u)/(u+v),(c.y*v+d.y*u)/(u+v));
}
double PolygonArea(Point p[],int n){
     if(n<3) return 0.0;
     double s=p[0].y*(p[n-1].x-p[1].x);
     p[n]=p[0];
     for(int i=1;i<n;i++){
        s+=p[i].y*(p[i-1].x-p[i+1].x);
     }
     return fabs(s*0.5);
}
double CPIA(Point a[],Point b[],int na,int nb){
    Point p[maxisn],temp[maxisn];
    int i,j,tn,sflag,eflag;
    a[na]=a[0],b[nb]=b[0];
    memcpy(p,b,sizeof(Point)*(nb+1));
    for(i=0;i<na&&nb>2;++i){
        sflag=dcmp(a[i].cross(a[i+1],p[0]));
        for(j=tn=0;j<nb;++j,sflag=eflag){
            if(sflag>=0) temp[tn++]=p[j];
            eflag=dcmp(a[i].cross(a[i+1],p[j+1]));
            if((sflag^eflag)==-2)
                temp[tn++]=LineCross(a[i],a[i+1],p[j],p[j+1]);
        }
        memcpy(p,temp,sizeof(Point)*tn);
        nb=tn,p[nb]=p[0];
    }
    if(nb<3) return 0.0;
    return PolygonArea(p,nb);
}
double SPIA(Point a[],Point b[],int na,int nb){
    int i,j;
    Point t1[4],t2[4];
    double res=0.0,if_clock_t1,if_clock_t2;
    a[na]=t1[0]=a[0];
    b[nb]=t2[0]=b[0];
    for(i=2;i<na;i++){
        t1[1]=a[i-1],t1[2]=a[i];
        if_clock_t1=dcmp(t1[0].cross(t1[1],t1[2]));
        if(if_clock_t1<0) swap(t1[1],t1[2]);
        for(j=2;j<nb;j++){
            t2[1]=b[j-1],t2[2]=b[j];
            if_clock_t2=dcmp(t2[0].cross(t2[1],t2[2]));
            if(if_clock_t2<0) swap(t2[1],t2[2]);
            res+=CPIA(t1,t2,3,3)*if_clock_t1*if_clock_t2;
        }
    }
    return res;//面积交
    //return PolygonArea(a,na)+PolygonArea(b,nb)-res;//面积并
}

Point a[222],b[222];
Point aa[222],bb[222];

int main(){


    double x1,y1,x2,y2;
    double x3,y3,x4,y4;
    while(scanf("%lf %lf %lf %lf",&x1,&y1,&x2,&y2)!=EOF){
        scanf("%lf %lf %lf %lf",&x3,&y3,&x4,&y4);
        a[0]=Point(x1,y1);   // 逆时针??
        a[1]=Point(x2,y1);
        a[2]=Point(x1,y2);

        b[0]=Point(x3,y3);
        b[1]=Point(x4,y3);
        b[2]=Point(x4,y4);
        b[3]=Point(x3,y4);

        printf("%.8f\n",fabs(SPIA(a,b,3,4)));
        //printf("%.8f\n",ConvexPolygonArea(out,m));
    }
    return 0;
}

圆与多边形相交

#include <iostream>
#include <cstdio>
#include <cmath>
#include <vector>
#include <cstring>
#include <algorithm>
#include <string>
#include <set>
#include <functional>
#include <numeric>
#include <sstream>
#include <stack>

#define CL(arr, val) memset(arr, val, sizeof(arr))
#define REP(i, n)for((i) = 0; (i) < (n); ++(i))
#define FOR(i, l, h)for((i) = (l); (i) <= (h); ++(i))
#define FORD(i, h, l)for((i) = (h); (i) >= (l); --(i))
#define L(x)(x) << 1
#define R(x)(x) << 1 | 1
#define MID(l, r)(l + r) >> 1
#define Min(x, y)x < y ? x : y
#define Max(x, y)x < y ? y : x
#define E(x)(1 << (x))
#define iabs(x) (x) < 0 ? -(x) : (x)
#define OUT(x)printf("%I64d\n", x)
#define lowbit(x)(x)&(-x)
#define Read()freopen("data.in", "r", stdin)
#define Write()freopen("data.out", "w", stdout);

const double eps = 1e-10;
typedef long long LL;
const int inf = ~0u>>2;

using namespace std;

inline double max (double a, double b) { if (a > b) return a; else return b; }
inline double min (double a, double b) { if (a < b) return a; else return b; }
inline int fi (double a)
{
    if (a > eps) return 1;
    else if (a >= -eps) return 0;
    else return -1;
}
class Vector
{
public:
    double x, y;
    Vector (void) {}
    Vector (double x0, double y0) : x(x0), y(y0) {}
    double operator * (const Vector& a) const { return x * a.y - y * a.x; }
    double operator % (const Vector& a) const { return x * a.x + y * a.y; }
    Vector verti (void) const { return Vector(-y, x); }
    double length (void) const { return sqrt(x * x + y * y); }
    Vector adjust (double len)
    {
        double ol = len / length();
        return Vector(x * ol, y * ol);
    }
    Vector oppose (void) { return Vector(-x, -y); }
};
class point
{
public:
    double x, y;
    point (void) {}
    point (double x0, double y0) : x(x0), y(y0) {}
    Vector operator - (const point& a) const { return Vector(x - a.x, y - a.y); }
    point operator + (const Vector& a) const { return point(x + a.x, y + a.y); }
};
class segment
{
public:
    point a, b;
    segment (void) {}
    segment (point a0, point b0) : a(a0), b(b0) {}
    point intersect (const segment& s) const
    {
        Vector v1 = s.a - a, v2 = s.b - a, v3 = s.b - b, v4 = s.a - b;
        double s1 = v1 * v2, s2 = v3 * v4;
        double se = s1 + s2;
        s1 /= se, s2 /= se;
        return point(a.x * s2 + b.x * s1, a.y * s2 + b.y * s1);
    }
    point pverti (const point& p) const
    {
        Vector t = (b - a).verti();
        segment uv(p, p + t);
        return intersect(uv);
    }
    bool on_segment (const point& p) const
    {
        if (fi(min(a.x, b.x) - p.x) <= 0 && fi(p.x - max(a.x, b.x)) <= 0 &&
            fi(min(a.y, b.y) - p.y) <= 0 && fi(p.y - max(a.y, b.y)) <= 0) return true;
        else return false;
    }
};

double radius;
point polygon[110];

double kuras_area (point a, point b, double cx, double cy)
{
    point ori(cx, cy);
    int sgn = fi((b - ori) * (a - ori));
    double da = (a - ori).length(), db = (b - ori).length();
    int ra = fi(da - radius), rb = fi(db - radius);
    double angle = acos(((b - ori) % (a - ori)) / (da * db));
    segment t(a, b); point h, u; Vector seg;
    double ans, dlt, mov, tangle;

    if (fi(da) == 0 || fi(db) == 0) return 0;
    else if (sgn == 0) return 0;
    else if (ra <= 0 && rb <= 0) return fabs((b - ori) * (a - ori)) / 2 * sgn;
    else if (ra >= 0 && rb >= 0)
    {
        h = t.pverti(ori);
        dlt = (h - ori).length();
        if (!t.on_segment(h) || fi(dlt - radius) >= 0)
            return radius * radius * (angle / 2) * sgn;
        else
        {
            ans = radius * radius * (angle / 2);
            tangle = acos(dlt / radius);
            ans -= radius * radius * tangle;
            ans += radius * sin(tangle) * dlt;
            return ans * sgn;
        }
    }
    else
    {
        h = t.pverti(ori);
        dlt = (h - ori).length();
        seg = b - a;
        mov = sqrt(radius * radius - dlt * dlt);
        seg = seg.adjust(mov);
        if (t.on_segment(h + seg)) u = h + seg;
        else u = h + seg.oppose();
        if (ra == 1) swap(a, b);
        ans = fabs((a - ori) * (u - ori)) / 2;
        tangle = acos(((u - ori) % (b - ori)) / ((u - ori).length() * (b - ori).length()));
        ans += radius * radius * (tangle / 2);
        return ans * sgn;
    }
}

const double pi = acos(-1.0);

int main ()
{
    //freopen("data.in", "r", stdin);
    //radius 为圆的半径
    int n;
    double area, x, y, cx, cy;//cx ,cy 为圆的坐标
    double x0, y0, v0, th, t, g;
    double vx, vy;
    while(cin>>cx>>cy>>radius)
    {
        int n;
            cin>>n;
        for(int i = 0; i < n; ++i) {
            scanf("%lf%lf", &x, &y);
            polygon[i] = point(x, y);
        }
        area = 0;
        for (int i = 0; i < n; i++)
            area += kuras_area(polygon[i], polygon[(i + 1) % n], cx, cy);
        printf("%.2f\n", fabs(area));
    }
    return 0;
}

kmp算法


#include <bits/stdc++.h>
using namespace std;
const int maxn=1e5+5;
int nex[maxn];
void getnext(string &b)
{
    memset(nex,0,sizeof(nex));
    for(int i=1,j=0;b[i];i++)
    {
        while(b[i]!=b[j]&&j>0 ) j=nex[j-1];
        if( b[i]==b[j] ) nex[i]=j+1,j++;
    }
}

int kmp(string &a,string &b)
{
    getnext(b);
    int len=b.size(),ans=0;
    for(int i=0,j=0;a[i];i++)
    {
        while(a[i]!=b[j] &&j>0 )
            j=nex[j-1];
        if(a[i]==b[j] ) j++;
        if(j==len)
            j=nex[j-1],ans++;
    }
    return ans;

}

int main()
{
    int t;
    cin>>t;
    while(t--)
    {
        string a,b;
        cin>>a>>b;
        cout<<kmp(b,a)<<endl;
    }
}







深度学习是机器学习的一个子领域,它基于人工神经网络的研究,特别是利用多层次的神经网络来进行学习和模式识别。深度学习模型能够学习数据的高层次特征,这些特征对于图像和语音识别、自然语言处理、医学图像分析等应用至关重要。以下是深度学习的一些关键概念和组成部分: 1. **神经网络(Neural Networks)**:深度学习的基础是人工神经网络,它是由多个层组成的网络结构,包括输入层、隐藏层和输出层。每个层由多个神经元组成,神经元之间通过权重连接。 2. **前馈神经网络(Feedforward Neural Networks)**:这是最常见的神经网络类型,信息从输入层流向隐藏层,最终到达输出层。 3. **卷积神经网络(Convolutional Neural Networks, CNNs)**:这种网络特别适合处理具有网格结构的数据,如图像。它们使用卷积层来提取图像的特征。 4. **循环神经网络(Recurrent Neural Networks, RNNs)**:这种网络能够处理序列数据,如时间序列或自然语言,因为它们具有记忆功能,能够捕捉数据中的时间依赖性。 5. **长短期记忆网络(Long Short-Term Memory, LSTM)**:LSTM 是一种特殊的 RNN,它能够学习长期依赖关系,非常适合复杂的序列预测任务。 6. **生成对抗网络(Generative Adversarial Networks, GANs)**:由两个网络组成,一个生成器和一个判别器,它们相互竞争,生成器生成数据,判别器评估数据的真实性。 7. **深度学习框架**:如 TensorFlow、Keras、PyTorch 等,这些框架提供了构建、训练和部署深度学习模型的工具和库。 8. **激活函数(Activation Functions)**:如 ReLU、Sigmoid、Tanh 等,它们在神经网络中用于添加非线性,使得网络能够学习复杂的函数。 9. **损失函数(Loss Functions)**:用于评估模型的预测与真实值之间的差异,常见的损失函数包括均方误差(MSE)、交叉熵(Cross-Entropy)等。 10. **优化算法(Optimization Algorithms)**:如梯度下降(Gradient Descent)、随机梯度下降(SGD)、Adam 等,用于更新网络权重,以最小化损失函数。 11. **正则化(Regularization)**:技术如 Dropout、L1/L2 正则化等,用于防止模型过拟合。 12. **迁移学习(Transfer Learning)**:利用在一个任务上训练好的模型来提高另一个相关任务的性能。 深度学习在许多领域都取得了显著的成就,但它也面临着一些挑战,如对大量数据的依赖、模型的解释性差、计算资源消耗大等。研究人员正在不断探索新的方法来解决这些问题。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值