自定义头文件

· · 个人记录

自定义头文件使用介绍

一、代码主体

struct Bignum{
    int len,s[maxm];
    Bignum(){
        len=1;
        memset(s,0,sizeof(s));
    }
    Bignum operator =(const char *num){
        len=strlen(num);
        rep(i,0,len-1) s[i]=(num[len-i-1]^48);
        return *this;
    }
    Bignum operator =(const int num){
        char a[maxm];
        sprintf(a,"%d",num);
        *this = a;
        return *this;
    }
    Bignum(int num){*this = num;}
    Bignum(const char *num){*this = num;}
    Bignum operator +(const Bignum &a){
        Bignum c;
        c.len=max(len,a.len)+1;
        for(int i=0,x=0;i<c.len;i++){
            c.s[i]=s[i]+a.s[i]+x;
            x=c.s[i]/10;
            c.s[i]%=10;
        }
        if(c.s[c.len-1]==0) c.len--;
        return c;
    }
    Bignum operator +=(const Bignum &a){
        *this = *this + a;
        return *this;
    }
    Bignum operator *(const Bignum &a){
        Bignum c;
        c.len=len+a.len;
        rep(i,0,len-1)
        {
            rep(j,0,a.len-1)
            {
                c.s[i+j] += s[i]*a.s[j];
                c.s[i+j+1] += c.s[i+j]/10;
                c.s[i+j] %= 10;
            }
        }
        if(c.s[c.len-1]==0) c.len--;
        return c;
    }
    Bignum operator *=(const Bignum &a){
        *this = *this * a;
        return *this;
    }
    bool operator <(const Bignum &x)const{
        if(len!=x.len) return len<x.len;
        for(int i=len-1;i>=0;i--) 
            if(s[i]!=x.s[i]) return s[i]<x.s[i];
        return false;
    }
    bool operator >(const Bignum &x)const{return x<*this;}
    bool operator <=(const Bignum &x)const{return !(x<*this);}
    bool operator >=(const Bignum &x)const{return !(*this<x);}
    bool operator ==(const Bignum &x)const{return !(*this<x||x<*this);}
    bool operator !=(const Bignum &x)const{return (*this<x||x<*this);}
};
ostream& operator <<(ostream &out,const Bignum &x){
    for(int i=x.len-1;i>=0;i--) cout<<x.s[i];
    return out;
}
istream& operator >>(istream &in,Bignum &x){
    char num[maxm];
    in>>num;
    x=num;
    return in;
}
class PrimeNumber{
    public:
        int tot=0,prime[maxn]={0};
        bool a[maxn]={0};
        inline bool isPrime(int x){
            if(x<=1) return 0;
            if(x==2) return 1;
            else if(!(x&1)) return 0;
            for(int i=3;i*i<=x;i+=2)
                if(x%i==0) return 0;
            return 1;
        }
        inline void EulerFind(int n){
            memset(a,1,sizeof(a));
            a[0]=a[1]=false;
            for(int i=2;i<=n;i++){
                if(a[i]==true){
                    prime[++tot]=i;
                }
                for(int j=1;j<=tot;j++){
                    int t=i*prime[j];
                    if(t>n) break;
                    a[t]=false;
                    if(i%prime[j]==0) break;
                }
            }
        }//欧拉筛  
};
class Dijkstra{
    private:
        struct node{
            int w,now;
            bool operator <(const node &x)const{
                return w>x.w;
            }
        };
        priority_queue<node> q;
    public:
        struct Edge{
            int from,to,w,next;
        }e[maxn];
        int head[maxn],tot,dis[maxn],s;
        bool vis[maxn];
        inline void add(int u,int v,int w){
            e[++tot].from=u;
            e[tot].to=v;
            e[tot].w=w;
            e[tot].next=head[u];
            head[u]=tot;
        }
        inline void dijkstra(){
            memset(dis,0x3f3f3f3f,sizeof(dis));
            dis[s]=0;
            q.push((node){0,s});
            while(!q.empty()){
                node x=q.top();q.pop();
                int u=x.now;
                if(vis[u]) continue; vis[u]=1;
                for(int i=head[u];i;i=e[i].next){
                    int v=e[i].to;
                    if(dis[v]>dis[u]+e[i].w){
                        dis[v]=dis[u]+e[i].w;
                        q.push((node){dis[v],v});
                    }
                }
            }
        }
};
class KMP{
    public:
        int n,m;
        char a[maxn],b[maxn];
        inline void pre(){
            n=strlen(a+1);
            m=strlen(b+1);
            p[1]=0;
            now=0;
            rep(i,1,m-1){
                while(now>0 && b[now+1]!=b[i+1]) now=p[now];
                if(b[now+1]==b[i+1]) now++;
                p[i+1]=now;
            }
        }
        inline void find(){
            now=0;
            rep(i,0,n-1){
                while(now>0 && b[now+1]!=a[i+1]) now=p[now];
                if(b[now+1]==a[i+1]) ++now;
                if(now==m){
                    printf("%d\n",(i+1)-m+1);
                    now=p[now];
                }
            }
            rep(i,1,m) printf("%d ",p[i]);
        }
        int p[maxn],now;
};
class ST{
    public:
        int n,m,a[maxn];
    inline void init(){
        n=read(),m=read();
        rep(i,1,n) a[i]=read();
        l[0]=-1;//l[i]= int [log2(i)]
        rep(i,1,n)
        {
            f[i][0]=a[i];
            l[i]=l[i>>1]+1;
        }
        rep(j,1,maxl)
        {
            for(int i=1;i+(1<<j)-1<=n;i++)
                f[i][j]=max(f[i][j-1],f[i+(1<<j-1)][j-1]);//Time: O(NlogN)
        }
    }
    inline int query(int x,int y){
        int k=l[y-x+1];
        return max(f[x][k],f[y-(1<<k)+1][k]);// Time: O(1)
    }
    private:
        #define re register
        #define gg (getchar())
        inline int read(){
            register int x=0,f=1;
            re char c=gg;
            while(!isdigit(c)){
                if(c=='-') f=-1;
                c=gg;
            }
            while(isdigit(c)){
                x=(x<<1)+(x<<3)+(c^48);
                c=gg;
            }
            return x*f;
        }
        #undef re
        #undef gg

        int l[maxn],f[maxn][maxl+5];//Memory: O(NlogN)
};
inline long long Pow(int a,int x){
    long long ans=1;
    while(x){
        if(x&1) ans*=a;
        a*=a;
        x>>=1;
    }
    return ans;
}
class BinaryIndexTree{
    private:
        int c[maxn];
        inline int lowbit(int x){return x&(-x);}
    public:
        #define Max(a,b) (a>b?a:b)
        int n;
        inline void update(int x,int v){
            for(;x<=n;x+=lowbit(x)) c[x]+=v;
        }
        inline int sum(int x) {
            int res=0;
            for(;x;x-=lowbit(x)) res+=c[x];
            return res;
        }
        #undef Max(a,b)
};
#define re register
#define gg (getchar())
inline ll input(){
    register ll x=0,f=1;
    re char c=gg;
    while(!isdigit(c)){
        if(c=='-') f=-1;
        c=gg;
    }
    while(isdigit(c)){
        x=(x<<1)+(x<<3)+(c^48);
        c=gg;
    }
    return x*f;
}
#undef re
#undef gg
struct SegmentTree{
    ll add[maxn<<2]={0},sum[maxn<<2]={0},mul[maxn<<2]={0},a[maxn];
    inline void pushdown(ll k,ll l,ll r){
        if(!add[k] && mul[k]==1) return ;
        ll len=r-l+1;
        sum[k<<1]=(sum[k<<1]*mul[k]+add[k]*(len-(len>>1)))%mod;
        sum[k<<1|1]=(sum[k<<1|1]*mul[k]+add[k]*(len>>1))%mod;
        add[k<<1]=(add[k<<1]*mul[k]+add[k])%mod;
        add[k<<1|1]=(add[k<<1|1]*mul[k]+add[k])%mod;
        (mul[k<<1]*=mul[k])%=mod;
        (mul[k<<1|1]*=mul[k])%=mod;
        add[k]=0;mul[k]=1;
    }   
    inline void build(ll k,ll l,ll r){
        add[k]=0;mul[k]=1;
        if(l==r){
            sum[k]=a[l]%mod;
            return ;
        }
        ll mid=(l+r)>>1;
        build(k<<1,l,mid);
        build(k<<1|1,mid+1,r);
        sum[k]=sum[k<<1]+sum[k<<1|1];sum[k]%=mod;
    }
    inline void multiply(ll k,ll l,ll r,ll x,ll y,ll v){
        pushdown(k,l,r);
        if(x<=l&&y>=r){
            (sum[k]*=v)%=mod;
            (mul[k]*=v)%=mod;
            return ;
        }
        ll mid=(l+r)>>1;
        if(x<=mid) multiply(k<<1,l,mid,x,y,v);
        if(y>mid) multiply(k<<1|1,mid+1,r,x,y,v);
        sum[k]=sum[k<<1]+sum[k<<1|1];sum[k]%=mod;
    }
    inline void update(ll k,ll l,ll r,ll x,ll y,ll v){
        pushdown(k,l,r);
        if(l==r){
            (sum[k]+=v*(r-l+1))%=mod;
            (add[k]+=v)%=mod;
            return ;
        }
        ll mid=(l+r)>>1;
        if(x<=mid) update(k<<1,l,mid,x,y,v);
        if(y>mid) update(k<<1|1,mid+1,r,x,y,v);
        sum[k]=(sum[k<<1]+sum[k<<1|1])%mod;
    }
    inline ll query(ll k,ll l,ll r,ll x,ll y){
        pushdown(k,l,r);
        if(x<=l&&y>=r) return sum[k];
        ll mid=(l+r)>>1;
        ll res=0;
        if(x<=mid) (res+=query(k<<1,l,mid,x,y))%=mod;
        if(y>mid) (res+=query(k<<1|1,mid+1,r,x,y))%=mod;
        return res;
    }   
};
class MST{
    private:
        int fa[maxn],n=0,m=0,ans=0;
        inline int find(int k){
            if(k==fa[k]) return fa[k];
            return fa[k]=find(fa[k]);
        }
    public:
        struct node{
            int u,v,w;
            bool operator <(const node &x)const{
                return w<x.w;
            }
        }a[maxn];
        inline void kruskal(){
            rep(i,1,n) fa[i]=i;
            int cnt=0;
            rep(i,1,m)
            {
                int f1=find(a[i].u);
                int f2=find(a[i].v);
                if(f1!=f2) {
                    ans+=a[i].w;
                    fa[f2]=f1;
                    cnt++;
                    if(cnt==n-1) break;
                }
            }
        }
        //<------------Kruskal-------------->
        const int inf=0x3f3f3f3f;
        struct Edge{
            int from,to,w,next;
        }e[maxn];
        int head[maxn],dis[maxn],tot,cnt;
        bool vis[maxn]; 
        inline void add(int u,int v,int w){
            e[++tot].to=v;
            e[tot].w=w;
            e[tot].next=head[u];
            head[u] = tot;
        }
        #define mp(x,y) make_pair(x,y)
        priority_queue< pair<int,int> > q;
        inline int prim(){
            q.push(mp(0,1));
            while(!q.empty() && cnt<=n-1){
                int now=q.top().second;
                int w=q.top().first;q.pop();
                if(vis[now]) continue;
                vis[now]=1;
                ans+=w;
                cnt++;
                for(int i=head[now];i;i=e[i].next){
                    int x=e[i].to;
                    if(!vis[x]){
                        q.push(mp(-e[i].w,x));
                    }
                }
            }
            return -ans;
        }
        #undef mp(x,y)
        //<-------------prim--------------->
};
#undef rep(ii,aa,bb)

二、功能介绍

本头文件基本包含了 c++ 常备头文件,如 iostream, cstdio, cmath, algorithm 等,可以实现库函数和 STL 的直接调用实现。更进一步地了解可以使用的库函数和 STL 容器请自行百度(由于这些均是已开发头文件)。

STL 容器大致包含了 vector, map, queue, priority_queue, stack, string, set等常用模板库。当然也可以自行更改 Mars.h 以添加。

接下来重点介绍手写的封装数据结构:

  1. 变量(常量)等可直接调用函数:

    • 长整型 ll;
    • 数值范围 maxm=4000用于高精位数,maxn=1e5+5, maxl=20用于 RMQ, mod=1e9+7
    • 循环简化 rep(i,a,b)
    • 读入优化 ll input()
    • 快速幂 ll Pow(int,int);
  2. 手写数据结构:

    • 高精加法乘法 Bignum,包括输入输出流的定义
    • 质数 PrimeNumber 中包含判断函数 bool isPrime(int) O(\sqrt n),以及欧拉筛 void EulerFind(int);
    • 最短路 Dijkstra 中包含链式前向星连边操作 adddijkstra 函数,O((n+m)\log m);
    • KMP 基本函数
    • RMQ 问题的 ST 中包含初始化 void init() 与查询最大值 int query(int,int)
    • 树状数组 BinaryIndexTree 的单点修改 void update(int,int) 和前缀和查询 int sum(int)
    • 线段树 SegmentTree;
    • 最小生成树 MSTvoid kruskal(), prim()