zoukankan      html  css  js  c++  java
  • 模板总结(不定期更新)

    写在前面:

    这里会挂一些自己认为很重要的模板,没理解的就没有注释了,等理解了就更
    

    排序算法模板:

    快速排序(简单分治思想,时间复杂度从(O_(nlog{n}))(O_(n^2))不等,及其不稳定)
    (code:)

    #include<iostream>
    using namespace std;
    long long a[100001],n;
    void qs(int l,int r){
        int bz=a[(l+r)/2],i=l,j=r;
        while(i<=j){
            while(a[i]<bz)++i;
            while(a[j]>bz)--j;
            if(i<=j)
                swap(a[i],a[j]),++i,--j;
        }
        if(l<j)qs(l,j);
        if(r>i)qs(i,r);
    }
    int main(){
        cin>>n;
        for(int i=1;i<=n;i++){
            cin>>a[i];
        }
        qs(1,n);
        for(int i=1;i<=n-1;i++)
            cout<<a[i]<<' ';
        cout<<a[n]<<endl;
        return 0;
    }
    

    题目链接

    归并排序(分治思想,时间复杂度稳定在(O_(nlog{n})))
    (Code:)

    #include<bits/stdc++.h>
    #define ll long long
    using namespace std;
    const int maxn=5e5+1;
    inline int read(){
        char ch=getchar();
        int r=0,s=1;
        while(ch>57||ch<48)s=ch==45?0:s,ch=getchar();
        while(ch>=48&&ch<=57)r=(r<<1)+(r<<3)+(ch^48),ch=getchar();
        return s?r:-r;
    }
    int n;
    int a[maxn],tmp[maxn];
    void ms(int l,int r){
        if(l==r)return;
        int mid=(l+r)>>1,i=l,j=mid+1,cnt=l;
        ms(l,mid);
        ms(mid+1,r);
        while(i<=mid&&j<=r){
            if(a[j]>=a[i])tmp[cnt]=a[i],i++,cnt++;
            if(a[i]>a[j])tmp[cnt]=a[j],j++,cnt++;
        }
        while(i<=mid)tmp[cnt]=a[i],i++,cnt++;
        while(j<=r)tmp[cnt]=a[j],j++,cnt++;
        for(i=l;i<=r;++i)a[i]=tmp[i];
        return;
    }
        
    int main(){
        n=read();
        for(int i=1;i<=n;++i)a[i]=read();
        ms(1,n);
        for(int i=1;i<=n;++i)printf("%d ",a[i]);
        return 0;
    }
    
    

    排序算法结束

    图论算法模板

    单源最短路径:

    (SPFA)(死了的那个,时间复杂度(O_(km))(O_(nm)),不被卡就会跑得飞快)

    (Code:)

    const int maxn=1e5+5,maxm=5e5+5;
    queue< int > q;
    struct edge{int to,nxt,w;}e[maxm<<1]
    int head[maxn],dis[maxn],v[maxn];
    void SPFA(int s){
        int x,y,z;
        memset(dis,0x3f,sizeof(dis));
        memset(v,0,sizeof(v));
        dis[s]=0,v[s]=1,q.push(s);
        while(!q.empty()){
            x=q.front(),v[x]=0,q.pop();
            for(int i=head[x];i;i=e[i].nxt){
                y=e[i].to,z=e[i].w;
                if(dis[y]>dis[x]+z){
                    dis[y]=dis[x]+z;
                    if(!v[y])v[y]=1,q.push(y);
                }
            }
        }
        return;
    }
    

    (Dijkstra)(没有(SPFA)的时候要坚强,多写写堆优化,时间复杂度(O_((n+m)log{n})))

    (Code:)

    const int maxn=1e5+5,maxm=5e5+5;
    priority_queue< pair< int , int > > q;
    struct edge{int to,nxt,w;}e[maxm<<1]
    int head[maxn],dis[maxn],vis[maxn];
    void Dijkstra(int s){
        int x,y,z;
        memset(dis,0x3f,sizeof(dis));
        memset(v,0,sizeof(vis));
        dis[s]=0,q.push(make_pair(0,s));
        while(!q.empty()){
            x=q.top().second,q.pop();
            if(vis[x])continue;
            vis[x]=1;
            for(int i=head[x];i;i=e[i].nxt){
                y=e[i].to,z=e[i].w;
                if(dis[y]>dis[x]+z){
                    dis[y]=dis[x]+z;
                    if(!vis[y])q.push(make_pair(-dis[y],y));
                }
            }
        }
        return;
    }
    

    (Prim + Priority Queue)(时间复杂度为(O_(mlog{n})),稠密图上表现较优)

    (Code:)

    const int maxn=5005,maxm=2e5+5;
    priority_queue< pair< int , int > > q;
    struct edge{int to,nxt,w;}e[maxm<<1];
    int n,m,cnt,ans,tot;
    int head[maxn],dis[maxn],vis[maxn];
    
    void Prim(){
    	int x,y,z;
    	memset(dis,0x3f,sizeof(dis));
    	memset(vis,0,sizeof(vis));
    	dis[1]=0,q.push(make_pair(0,1));
    	while(q.size()){
    		x=q.top().second,q.pop();
    		if(vis[x])continue;
    		vis[x]=1,ans+=dis[x],++tot;
    		for(re int i=head[x];i;i=e[i].nxt){
    			y=e[i].to,z=e[i].w;
    			if(dis[y]>z){
    				dis[y]=z;
    				if(!vis[y])q.push(make_pair(-dis[y],y));
    			}
    		}
    	}
    	return;
    }
    

    (Kruskal)(时间复杂度为(O_(mlog{m}+malpha(n))))

    (Code:)

    #define re register
    const int maxn=5005,maxm=2e5+5;
    struct edge{int u,v,w;}e[maxm];
    int n,m,pd=1;
    int f[maxn];
    
    bool cmp(edge x,edge y){return x.w<y.w;}
    
    inline int fin(int x){return f[x]==x?x:f[x]=fin(f[x]);}
    
    void Kruskal(){
        int f1,f2,k;
        sort(e+1,e+m+1,cmp);
        for(re int i=1;i<=n;++i)f[i]=i;
        for(re int i=1;i<=m;++i){
            f1=fin(e[i].u),f2=fin(e[i].v);
            if(f1==f2)continue;
            f[f1]=f2;
            ans+=e[i].w;
            if(++k==n-1)break;
        }
        if(k<n-1)pd=0;
        return;
    }
    
    

    (Prim + PriorityQueue)(时间复杂度为(O_(mlog{n})),稠密图上表现较优)

    (Code:)

    const int maxn=5005,maxm=2e5+5;
    priority_queue< pair< int , int > > q;
    struct edge{int to,nxt,w;}e[maxm<<1];
    int n,m,cnt,ans,tot;
    int head[maxn],dis[maxn],vis[maxn];
    
    void Prim(){
    	int x,y,z;
    	memset(dis,0x3f,sizeof(dis));
    	memset(vis,0,sizeof(vis));
    	dis[1]=0,q.push(make_pair(0,1));
    	while(q.size()){
    		x=q.top().second,q.pop();
    		if(vis[x])continue;
    		vis[x]=1,ans+=dis[x],++tot;
    		for(re int i=head[x];i;i=e[i].nxt){
    			y=e[i].to,z=e[i].w;
    			if(dis[y]>z){
    				dis[y]=z;
    				if(!vis[y])q.push(make_pair(-dis[y],y));
    			}
    		}
    	}
    	return;
    }
    

    (Kruskal)(时间复杂度为(O_(mlog{m}+malpha(n))))

    (Code:)

    #define re register
    const int maxn=5005,maxm=2e5+5;
    struct edge{int u,v,w;}e[maxm];
    int n,m,pd=1;
    int f[maxn];
    
    bool cmp(edge x,edge y){return x.w<y.w;}
    
    inline int fin(int x){return f[x]==x?x:f[x]=fin(f[x]);}
    
    void Kruskal(){
        int f1,f2,k;
        sort(e+1,e+m+1,cmp);
        for(re int i=1;i<=n;++i)f[i]=i;
        for(re int i=1;i<=m;++i){
            f1=fin(e[i].u),f2=fin(e[i].v);
            if(f1==f2)continue;
            f[f1]=f2;
            ans+=e[i].w;
            if(++k==n-1)break;
        }
        if(k<n-1)pd=0;
        return;
    }
    
    

    图论算法结束

    (nlog{n})数据结构:

    树状数组(可用于求前缀和)

    (Code:)

    #define lowbit(x) (x&-x)
    const int maxn=5e5+5;
    
    int n;
    int a[maxn],c[maxn];
    
    void update(int x,int y){//更新
        while(x<=n){
            c[x]+=y;
            x+=lowbit(x);
        }
        return;
    }
    
    int sum(int x){//查询前缀和
        int ans=0;
        while(x>0){
            ans+=c[x];
            x-=lowbit(x);
        }
        return ans;
    }
    

    线段树:

    (Code:)

    #include<bits/stdc++.h>
    #define ll long long
    #define lc(x) (x<<1)
    #define rc(x) (x<<1|1)
    #define midd ((l+r)>>1)
    using namespace std;
    const int maxn=1e5+5;
    inline int read(){
        char ch=getchar();
        int r=0,s=1;
        while(ch>57||ch<48)s=ch==45?0:s,ch=getchar();
        while(ch>=48&&ch<=57)r=r*10+ch-48,ch=getchar();
        return s?r:-r;
    }
    
    ll sum[maxn<<2],tagm[maxn<<2],taga[maxn<<2],a[maxn];
    int n,m;
    ll HA;
    
    void push_up(int p){
        sum[p]=(sum[lc(p)]%HA+sum[rc(p)]%HA)%HA;
        return;
    }
    
    void build(int p,int l,int r){
        tagm[p]=1,taga[p]=0;
        if(l==r){sum[p]=a[l];return;}
        int mid=midd;
        build(lc(p),l,mid);build(rc(p),mid+1,r);
        push_up(p);
        return;
    }
    
    void push_down(int p,int l,int r){
        int mid=midd;
        sum[lc(p)]=((sum[lc(p)]*tagm[p])+(taga[p]*(mid-l+1)))%HA;
        sum[rc(p)]=((sum[rc(p)]*tagm[p])+(taga[p]*(r-mid)))%HA;
        taga[lc(p)]=(tagm[p]*taga[lc(p)]+taga[p])%HA,tagm[lc(p)]=(tagm[lc(p)]*tagm[p])%HA;
        taga[rc(p)]=(tagm[p]*taga[rc(p)]+taga[p])%HA,tagm[rc(p)]=(tagm[rc(p)]*tagm[p])%HA;
        taga[p]=0,tagm[p]=1;
        return;
    }
    
    void update_mul(int p,int l,int r,int cl,int cr,int k){
        if(cl>r||cr<l)return;
        if(cl<=l&&r<=cr){sum[p]=(sum[p]*k)%HA,tagm[p]=(tagm[p]*k)%HA,taga[p]=(taga[p]*k)%HA;return;}
        push_down(p,l,r);
        int mid=midd;
        if(mid>=cl) update_mul(lc(p),l,mid,cl,cr,k);
        if(cr>mid) update_mul(rc(p),mid+1,r,cl,cr,k);
        push_up(p);
        return;
    }
    
    void update_add(int p,int l,int r,int cl,int cr,int k){
        if(cl>r||cr<l)return;
        if(cl<=l&&r<=cr){sum[p]=(sum[p]%HA+((r-l+1)*k)%HA)%HA,taga[p]=(taga[p]+k)%HA;return;}
        push_down(p,l,r);
        int mid=midd;
        if(cl<=mid)update_add(lc(p),l,mid,cl,cr,k);
        if(cr>mid)update_add(rc(p),mid+1,r,cl,cr,k);
        push_up(p);
        return;
    }
    
    ll ask(int p,int l,int r,int al,int ar){
        if(al>r||ar<l)return 0;
        if(al<=l&&r<=ar)return sum[p];
        push_down(p,l,r);
        ll ans=0;
        int mid=midd;
        if(al<=mid) ans=(ans+ask(lc(p),l,mid,al,ar))%HA;
        if(ar>mid) ans=(ans+ask(rc(p),mid+1,r,al,ar))%HA;
        return ans;
    }
    
    int main(){
        n=read(),m=read();
        scanf("%lld",&HA);
        for(int i=1;i<=n;++i)a[i]=read();
        build(1,1,n);
        int k,x,y,z;
        while(m--){
            k=read();
            switch(k){
            case 1:x=read(),y=read(),z=read(),update_mul(1,1,n,x,y,z);break;
            case 2:x=read(),y=read(),z=read(),update_add(1,1,n,x,y,z);break;
            case 3:x=read(),y=read(),printf("%lld
    ",ask(1,1,n,x,y));break;
            default:break;
            }
        }
        return 0;
    }
    
    

    乱入一个分块2333

    #define ll long long
    #define re register
    void build(){
        re int s=sqrt(n);
        re int num=n/s;
        if(n%s)++num;
        for(re int i=1;i<=n;++i)pos[i]=(i-1)/s+1,sum[(i-1)/s+1]+=a[i];
        for(re int i=1;i<=num;++i)l[i]=(i-1)*s+1,r[i]=i*s;
        r[num]=n;
        return;
    }
    
    void update(int le,int ri,int d){
        re int x=pos[le],y=pos[ri];
        if(x==y){for(re int i=le;i<=ri;++i)a[i]+=d,sum[x]+=d;return;}
        for(re int i=le;i<=r[x];++i)a[i]+=d,sum[x]+=d;
        for(re int i=l[y];i<=ri;++i)a[i]+=d,sum[y]+=d;
        for(re int i=x+1;i<=y-1;++i)tag[i]+=d,sum[i]+=d*(r[i]-l[i]+1);
        return;
    }
    
    ll query(int le,int ri){
        re int x=pos[le],y=pos[ri];
        re ll ans=0;
        if(tag[x]){for(re int i=l[x];i<=r[x];++i)a[i]+=tag[x];tag[x]=0;}
        if(tag[y]){for(re int i=l[y];i<=r[y];++i)a[i]+=tag[y];tag[y]=0;}
        if(x==y){for(re int i=le;i<=ri;++i)ans+=a[i];return ans;}
        for(re int i=le;i<=r[x];++i)ans+=a[i];
        for(re int i=l[y];i<=ri;++i)ans+=a[i];
        for(re int i=x+1;i<=y-1;++i)ans+=sum[i];
        return ans;
    }
    
  • 相关阅读:
    MySQL数据库8(十九)外键
    MySQL数据库8(十八)用户权限管理
    HTML基本样式
    HTML5之部分新特性
    MySQL数据库8(十七)数据库的备份还原
    MySQL数据库8(十六)子查询
    MySQL数据库(十五)联合查询与连接查询
    MySQL数据库8(十四)聚合函数和运算符
    MySQL数据库8(十三)高级数据操作之select指令
    MySQL数据库8(十二)高级数据操作
  • 原文地址:https://www.cnblogs.com/dclicker/p/9914671.html
Copyright © 2011-2022 走看看