1. 程式人生 > >洛谷模板大匯總(可能敲不完了qaq)

洛谷模板大匯總(可能敲不完了qaq)

最長公共子序列 through typedef close 原來 show tex das ora

前言

  哇!突然發現搜索‘模板’能搜到一坨。。。開始了默默刷模板的漫長之路。。。就讓我最後在掙紮一下下吧!!!

  待續。。。持續更新中。。。

板砸們

1、P1177 【模板】快速排序

直通

好吧,不可相信這也是個模板。。

技術分享

雖然說的那麽。。那什麽。。可是,真的不想自己弄唉(STL大法好)

代碼醬=v=

①sort大法好!

技術分享
#include <iostream>
#include <cstdio>
#include <algorithm>
using namespace std;

int n;
long long a[100010]; int main() { scanf("%d",&n); for(int i=0; i<n; i++) scanf("%lld",&a[i]); sort(a,a+n); for(int i=0; i<n; i++) printf("%lld ",a[i]); return 0; }
View Code

②真板子

——快速排序

技術分享
#include <iostream>
#include <cstdio>
#include 
<algorithm> #define mid ((l+r)>>1) #define LL long long using namespace std; int n; LL a[100010]; void Mysort(int l,int r) { int i=l,j=r,m=a[mid]; while(i<=j) { while(a[i]<m) i++; while(a[j]>m) j--; if(i<=j) { LL tmp=a[i]; a[i]
=a[j],a[j]=tmp; i++,j--; } } if(l<j) Mysort(l,j); if(i<r) Mysort(i,r); } int main() { scanf("%d",&n); for(int i=0; i<n; i++) scanf("%lld",&a[i]); Mysort(0,n-1); for(int i=0; i<n; i++) printf("%lld ",a[i]); return 0; }
View Code

——歸並排序

技術分享
#include <iostream>
#include <cstdio>
#define LL long long
using namespace std;

const int M = 100010;
int n;
LL a[M],b[M];

void gsort(int l,int r) {
    if(l==r) return;
    int mid=l+r>>1;
    gsort(l,mid),gsort(mid+1,r);
    int i=l,j=mid+1,k=l;
    while(i<=mid && j<=r) {
        if(a[i]<=a[j]) b[k++]=a[i++];
        else b[k++]=a[j++];
    }
    while(i<=mid) b[k++]=a[i++];
    while(j<=r) b[k++]=a[j++];
    for(int q=l; q<=r; q++) a[q]=b[q];
}

int main() {
    scanf("%d",&n);
    for(int i=1; i<=n; i++) scanf("%lld",&a[i]);
    gsort(1,n);
    for(int i=1; i<=n; i++) printf("%lld ",a[i]);
    return 0;
}
View Code

2、P1439 【模板】最長公共子序列

直通

  我以前原來沒做過qaq,這樣的板子題。。意會了好久233

思路

  我們可以以第一個串為標準,用第二個串來匹配第一個串,看能匹配多少。

  所以,其實第一個串的每個數字其實影響不大,只有知道它對應了第二串的哪個數字就行,然後最後只要求一下上升序列就好辣~

代碼醬qaq

技術分享
#include <iostream>
#include <cstdio>
#include <algorithm>
using namespace std;

const int M = 100010;
int n,len;
int a[M],b[M],belong[M];

int main() {
    scanf("%d",&n);
    //離散化一下 
    for(int i=1,x; i<=n; i++) {
        scanf("%d",&x);
        belong[x]=i;
    } 
    for(int i=1,x; i<=n; i++) {
        scanf("%d",&x);
        a[i]=belong[x];
    }
    for(int i=1; i<=n; i++) { //find上升序列 
        if(a[i]>b[len]) {
            b[++len]=a[i];
            continue;
        }
        int k=lower_bound(b+1,b+1+len,a[i])-b; 
        b[k]=a[i];
    }
    printf("%d\n",len);
    return 0;
}
View Code

3.P3390 【模板】矩陣快速冪

直通

今天剛學會qaq,考前的學新東西之一233

具體的嘛~我表示,只會背過+推矩陣

代碼醬=w=

技術分享
#include <iostream>
#include <cstdio>
typedef long long LL;
using namespace std;

inline LL readl() {
    LL x=0,f=1; char c=getchar();
    while(c<0 || c>9) { if(c==-) f=-1; c=getchar(); }
    while(c>=0 && c<=9) x=x*10+c-0,c=getchar();
    return x*f;
}

const int Mod = 1000000007;
LL n,m,i,j,k;
struct A {
    LL a[105][105];
    inline A operator * (const A &b) const {
        A ret;
        for(LL i=1; i<=n; i++)
            for(LL j=1; j<=n; j++) {
                ret.a[i][j]=0;
                for(LL k=1; k<=n; k++)
                    ret.a[i][j]+=a[i][k]*b.a[k][j],
                    ret.a[i][j]%=Mod;
            }
        return ret;
    }
}q;

A ksm(A a,LL x) {
    A ret,k;
    ret=a,k=a;
    x--;
    for(; x; x>>=1,k=k*k)
        if(x&1) ret=ret*k;
    return ret;
}

int main() {
    n=readl();m=readl();
    for(i=1; i<=n; i++)
        for(j=1; j<=n; j++)
            q.a[i][j]=readl();
    q=ksm(q,m);
    for(i=1; i<=n; i++) {
        for(j=1; j<n; j++) printf("%d ",q.a[i][j]);
        printf("%d\n",q.a[i][n]);
    }
    return 0;
}
View Code

4.P1939 【模板】矩陣加速(數列)

直通

思路

先看這個特征方程F[i] = F[i - 1] + F[i - 3],那麽就有一個矩陣如下

技術分享

我們的目標矩陣就是

技術分享

那麽,針對這個矩陣我們如何轉置呢?

先看目標矩陣第一個:F[i]

F[i] = F[i - 1] + F[i - 3]

那麽,由矩陣乘法,轉置矩陣第一行,似乎就定了:1 0 1

同樣的,二三行就是1 0 0 和 0 1 0

整個矩陣如下:

技術分享

至於轉置矩陣和初始矩陣的用法?

矩陣快速冪什麽各種雜七雜八的

直通

代碼醬_(:з」∠)_

技術分享
#include <iostream>
#include <cstdio>
#define LL long long 
using namespace std;

inline LL read() {
    LL x=0,f=1; char c=getchar();
    while(c<0 || c>9) { if(c==-) f=-1; c=getchar(); }
    while(c>=0 && c<=9) x=x*10+c-48,c=getchar();
    return x*f;
}

const int Mod = 1000000007;
LL T,n;
struct Q {
    LL a[5][5];
    Q operator * (const Q &b) const {
        Q ret;
        for(int i=1; i<=3; i++) 
            for(int j=1; j<=3; j++) {
                ret.a[i][j]=0;
                for(int k=1; k<=3; k++) 
                    ret.a[i][j]+=a[i][k]*b.a[k][j];
                    ret.a[i][j]%=Mod;
            }
        return ret;
    }
}A,B;

inline Q ksm(Q A,LL x) {
    Q ret=A,k=A;
    x--;
    for(; x; x>>=1,k=k*k)
        if(x&1) ret=ret*k;
    return ret;
}

int main() {
    T=read();
    while(T--) {
        n=read();
        if(n<=3) {
            printf("1\n");
            continue;
        }
        else {
            A.a[1][1]=A.a[1][3]=A.a[2][1]=A.a[3][2]=1;
            A.a[1][2]=A.a[2][2]=A.a[2][3]=A.a[3][1]=A.a[3][3]=0;
            B.a[1][1]=B.a[1][2]=B.a[1][3]=1;
            Q P=ksm(A,n);
            printf("%lld\n",P.a[1][3]);
        }
    }
    return 0;
} 
View Code

5.P3367 【模板】並查集

直通

呼~今天剛整理了這個qaq,還好還有印象。。。

代碼醬(≧▽≦)/

技術分享
#include <iostream>
#include <cstdio>
using namespace std;

const int N = 10010;
int n,m;
int dad[N];

inline int getdad(int x) {
    return x == dad[x] ? x : dad[x]=getdad(dad[x]);
}

inline void Union(int u,int v) {
    int f1=getdad(u),f2=getdad(v);
    if(f1!=f2) dad[f1]=f2;
}

int main() {
    scanf("%d%d",&n,&m);
    for(int i=1; i<=n; i++) dad[i]=i;
    for(int i=1,x,u,v; i<=m; i++) {
        scanf("%d%d%d",&x,&u,&v);
        if(x==1) {
            Union(u,v);
        }
        else {
            int f1=getdad(u),f2=getdad(v);
            if(f1!=f2) printf("N\n");
            else printf("Y\n");
        }
    }
    return 0;
}
View Code

6.P3372 【模板】線段樹 1

直通

坑點

第一次交上竟然WA了qaq,我我我我原來是更新區間的時候忘記乘以長度了qaq,再犯蠢就打我自己qaq

代碼醬TAT

技術分享
#include <iostream>
#include <cstdio>
#define mid ((l+r)>>1)
#define lson rt<<1
#define rson rt<<1|1
#define LL long long
using namespace std;

const int M = 100001;
int n,m,a,b,x,s[M];
LL ans;
struct Tree {
    LL l,r,w,f;
} t[M<<2];

inline void update(int rt) {
    int l=t[rt].l,r=t[rt].r;
    t[rt].w=t[lson].w+t[rson].w;
}

inline void build(int rt,int l,int r) {
    t[rt].l=l,t[rt].r=r,t[rt].f=0;
    if(l==r) {
        t[rt].w=s[l];
        return ;
    }
    build(lson,l,mid);
    build(rson,mid+1,r);
    update(rt);
}

inline void down(int rt) {
    int l=t[rt].l,r=t[rt].r;
    t[lson].f+=t[rt].f;
    t[rson].f+=t[rt].f;
    t[lson].w+=t[rt].f*(t[lson].r-t[lson].l+1);
    t[rson].w+=t[rt].f*(t[rson].r-t[rson].l+1);
    t[rt].f=0;
}

inline void addq(int rt) {
    int l=t[rt].l,r=t[rt].r;
    if(a<=l && r<=b) {
        t[rt].f+=x;
        t[rt].w+=(t[rt].r-t[rt].l+1)*x;
        return ;
    }
    if(t[rt].f) down(rt);
    if(a<=mid) addq(lson);
    if(b>mid) addq(rson);
    update(rt);
}

inline void asksum(int rt) {
    int l=t[rt].l,r=t[rt].r;
    if(a<=l && r<=b) {
        ans+=t[rt].w;
        return ;
    }
    if(t[rt].f) down(rt);
    if(a<=mid) asksum(lson);
    if(b>mid) asksum(rson);
}

int main() {
    scanf("%d%d",&n,&m);
    for(int i=1; i<=n; i++) scanf("%lld",&s[i]);
    build(1,1,n);
    for(int i=1,q; i<=m; i++) {
        scanf("%d",&q);
        if(q==1) {
            scanf("%d%d%d",&a,&b,&x);
            addq(1);
        }
        else {
            scanf("%d%d",&a,&b);
            asksum(1);
            printf("%lld\n",ans);
            ans=0;
        }
    }
    return 0;
}
View Code

洛谷模板大匯總(可能敲不完了qaq)