数据结构 & 算法模板汇总

#include <cstdio>
#include <iostream>
#include <algorithm>
#include <queue>
#include <cstring>
#define lowbit(x) (x&(-x)) 
using namespace std;
typedef long long ll;
typedef double db;
const ll eps=1e-8,N=200010;
ll n,m,x,y,z,a[N],sz=0,head[N],F=0,f[N],fa[N];
char opt[6];
ll read(){
    ll x=0,f=1;char ch=getchar();
    for (;ch<'0'||ch>'9';ch=getchar()) if (ch=='-') f=-1;
    for (;ch>='0'&&ch<='9';ch=getchar()) x=x*10+ch-'0';
    return x*f;
}
bool dbcmp(db x){
    return x<-eps?-1:x>eps?1:0;
}
struct Mat{
    ll s[2][2];
    ll* operator [](ll x){
        return s[x];
    }
    friend Mat operator *(Mat a,Mat b){
        Mat s={0,0,0,0};
        for (ll i=0;i<2;i++)
            for (ll j=0;j<2;j++)
                for (ll k=0;k<2;k++)
                    s[i][j]+=a[i][k]*b[k][j];
        return s;
    }
};
struct Graph{
    struct E{
        ll next,fa,to,w;
        friend bool operator <(E a,E b){
            return a.w<b.w;
        }
    }e[N];
    void insert(ll a,ll b,ll w){
        sz++;
        e[sz].next=head[a];
        head[a]=sz;
        e[sz].fa=a;
        e[sz].to=b;
        e[sz].w=w;
    }
    ll find(ll x){
        if (x==fa[x]) return x;
        return fa[x]=find(fa[x]);
    }
    void dijkstra(ll x){
        memset(f,0x7f,sizeof(f));
        typedef pair<ll,ll> P;
        priority_queue<P,vector<P>,greater<P> > que;
        que.push(P(0,x));f[x]=0;
        while(!que.empty()){
            ll x=que.top().second;que.pop();
            for (ll i=head[x];i;i=e[i].next){
                if (f[e[i].to]>f[x]+e[i].w){
                    f[e[i].to]=f[x]+e[i].w;
                    que.push(P(f[e[i].to],e[i].to));
                }
            }
        }
    }
    ll kruskal(){
        ll s=0;
        for (ll i=1;i<=n;i++) fa[i]=i;
        sort(e+1,e+sz+1);
        for (ll i=1;i<=sz;i++){
            ll a=find(e[i].fa),b=find(e[i].to);
            if (a!=b){
                fa[a]=b;
                s+=e[i].w;
            }
        }
        return s;
    }
}; 
struct FTree{
    ll t[N];
    void add(ll x,ll v){
        for (ll i=x;i<=n;i+=lowbit(i)) t[i]+=v;
    }
    ll query(ll x){
        ll s=0;
        for (ll i=x;i>=1;i-=lowbit(i)) s+=t[i]; 
        return s;
    }
};
struct SumSTree{
    struct P{
        ll l,r,v,tag;
    }t[4*N];
    ll build(ll x,ll l,ll r){
        t[x].l=l,t[x].r=r,t[x].tag=0;
        if (l==r) return t[x].v=a[l];
        ll mid=(l+r)/2;
        return t[x].v=build(x*2,l,mid)+build(x*2+1,mid+1,r);
    }
    void pushdown(ll x){
        if (!t[x].tag) return;
        t[x*2].v+=(t[x*2].r-t[x*2].l+1)*t[x].tag;
        t[x*2+1].v+=(t[x*2+1].r-t[x*2+1].l+1)*t[x].tag;
        t[x*2].tag+=t[x].tag;
        t[x*2+1].tag+=t[x].tag;
        t[x].tag=0;
    }
    void add(ll x,ll l,ll r,ll v){
        t[x].v+=(r-l+1)*v;
        if (l==t[x].l&&r==t[x].r){t[x].tag+=v;return;}
        pushdown(x);
        ll mid=(t[x].l+t[x].r)/2;
        if (r<=mid) add(x*2,l,r,v);
        else if (l>=mid+1) add(x*2+1,l,r,v);
        else add(x*2,l,mid,v),add(x*2+1,mid+1,r,v);
    }
    ll query(ll x,ll l,ll r){
        if (l==t[x].l&&r==t[x].r) return t[x].v;
        pushdown(x);
        ll mid=(t[x].l+t[x].r)/2;
        if (r<=mid) return query(x*2,l,r);
        else if (l>=mid+1) return query(x*2+1,l,r);
        else return query(x*2,l,mid)+query(x*2+1,mid+1,r);
    }
};
struct MaxSTree{
    struct P{
        ll l,r,v,tag;
    }t[4*N];
    ll build(ll x,ll l,ll r){
        t[x].l=l,t[x].r=r,t[x].tag=0;
        if (l==r) return t[x].v=a[l];
        ll mid=(l+r)/2;
        return t[x].v=max(build(x*2,l,mid),build(x*2+1,mid+1,r));
    }
    void pushdown(ll x){
        if (!t[x].tag) return;
        t[x*2].v+=t[x].tag;
        t[x*2+1].v+=t[x].tag;
        t[x*2].tag+=t[x].tag;
        t[x*2+1].tag+=t[x].tag;
        t[x].tag=0;
    }
    ll add(ll x,ll l,ll r,ll v){
        if (l==t[x].l&&r==t[x].r){t[x].tag+=v;return t[x].v+=v;}
        pushdown(x);
        ll mid=(t[x].l+t[x].r)/2;
        if (r<=mid) return t[x].v=max(t[x*2+1].v,add(x*2,l,r,v));
        else if (l>=mid+1) return t[x].v=max(t[x*2].v,add(x*2+1,l,r,v));
        else return t[x].v=max(add(x*2,l,mid,v),add(x*2+1,mid+1,r,v));
    }
    ll query(ll x,ll l,ll r){
        if (l==t[x].l&&r==t[x].r) return t[x].v;
        pushdown(x);
        ll mid=(t[x].l+t[x].r)/2;
        if (r<=mid) return query(x*2,l,r);
        else if (l>=mid+1) return query(x*2+1,l,r);
        else return max(query(x*2,l,mid),query(x*2+1,mid+1,r));
    }
};
struct KDTree{
    struct P{
        ll d[2],mx[2],mn[2],v,l,r,sum;
        ll& operator [](ll x){
            return d[x];
        }
        friend bool operator <(P a,P b){
            return a[F]<b[F]; 
        } 
    }t[N];
    void update(ll x){
        ll l=t[x].l,r=t[x].r;
        for (ll i=0;i<2;i++){
            t[x].mn[i]=t[x].mx[i]=t[x][i];
            if (l) t[x].mn[i]=min(t[x].mn[i],t[l].mn[i]),t[x].mx[i]=max(t[x].mx[i],t[l].mx[i]);
            if (r) t[x].mn[i]=min(t[x].mn[i],t[r].mn[i]),t[x].mx[i]=max(t[x].mx[i],t[r].mx[i]);
        }
        t[x].sum=t[x].v+t[l].sum+t[r].sum;
    }
    ll build(ll l,ll r){
        ll mid=(l+r)/2;
        nth_element(t+l,t+mid,t+r+1);
        F=!F;
        if (l<mid) t[mid].l=build(l,mid-1);
        if (r>mid) t[mid].r=build(mid+1,r);
        update(mid);
        return mid;
    }
};
int main(){
}
#include <cstdio>
#include <iostream>
#include <algorithm>
#include <cmath>
using namespace std;
typedef double db;
const int N=10010;
int n;
struct P{
    db x,y;
}p[N],sta[N];
db direct(P a,P b,P c){//cbbc aaaa xyxy l<0 r>0
    return (c.x-a.x)*(b.y-a.y)-(b.x-a.x)*(c.y-a.y);
}
bool cmp(P a,P b){//a<b l:b
    return direct(p[1],a,b)<0;
}
db graham(){
    db s=0;int k=1,top=2;
    for (int i=1;i<=n;i++) if ((p[i].y>p[k].y)||(p[i].y==p[k].y&&p[i].x<p[k].x)) k=i;
    swap(p[1],p[k]);
    sort(p+2,p+n+1,cmp);
    sta[1]=p[1],sta[2]=p[2];
    for (int i=3;i<=n;i++){
        while(top>=2&&direct(sta[top-1],sta[top],p[i])>0) top--;
        sta[++top]=p[i];
    }
    sta[++top]=p[1];
    for (int i=1;i<top;i++) s+=hypot(sta[i].x-sta[i+1].x,sta[i].y-sta[i+1].y);
    return s;
}
bool intersect(P a1,P a2,P b1,P b2){
    return
    min(a1.x,a2.x)<=max(b1.x,b2.x)&&
    min(b1.x,b2.x)<=max(a1.x,a2.x)&&
    min(a1.y,a2.y)<=max(b1.y,b2.y)&&
    min(b1.y,b2.y)<=max(a1.y,a2.y)&&
    direct(a1,a2,b1)*direct(a1,a2,b2)<=0&&
    direct(b1,b2,a1)*direct(b1,b2,a2)<=0;
}
int main(){
    scanf("%d",&n);
    for (int i=1;i<=n;i++) scanf("%lf %lf",&p[i].x,&p[i].y);
    printf("%.2lf",graham()); 
}
原文地址:https://www.cnblogs.com/algonote/p/7802077.html