模板库

「Pre」

临近 CSP-S2 2021 的时候,我决定把板子都打一遍,顺便就把这些板子整理成一个模板库罢

然而 CSP-S2 2021 都爆了我还没整完(

现在备战 NOIP2022 了(

本模板库最新的内容为 2022.2.20 更新,最老内容为 2022.1.23 更新,最近的码风翻新日期为 2022.1.23.

以下代码若无特殊情况皆可使用的缺省源:

UPD 2022.1.23

#include <bits/stdc++.h>

#define Heriko return
#define Deltana 0
#define Romanno 1
#define S signed
#define LL long long
#define DB double
#define R register
#define I inline
#define CI const int
#define CL const long long
#define mkp(a,b) make_pair(a,b)
#define mst(a,b) memset(a,b,sizeof(a))
#define ON std::ios::sync_with_stdio(false);cin.tie(0)
#define Files() freopen("RNMTQ.in","r",stdin);freopen("RNMTQ.out","w",stdout)

using namespace std;

template<typename J>
I void fr(J &x) {
    short f(1);
    x=0;
    char c(getchar());

    while(c<'0' or c>'9') {
        if(c=='-')
            f=-1;
        
        c=getchar();
    }

    while(c>='0' and c<='9') {
        x=(x<<3)+(x<<1)+(c^=48);
        c=getchar();
    }
   
    x*=f;
}

template<typename J>
I void fw(J x,bool k) {
    if(x<0)
        x=-x,putchar('-');

    static short stak[35];
    short top(0);

    do {
        stak[top++]=x%10;
        x/=10;
    }
    while(x);

    while(top)
        putchar(stak[--top]+'0');

    k?puts(""):putchar(' ');
}

「快速排序」

UPD 2022.1.23

CI MXX(1e5+1);

int a[MXX];

void Mysort(int l,int r) {
    int i(l),j(r),mid(a[(l+r)>>1]);
    
    do {
        while(a[i]<mid)
            ++i;
        
        while(a[j]>mid)
            --j;

        if(i<=j)
            swap(a[i],a[j]),++i,--j;
    }
    while(i<=j);
    
    if(l<j)
        Mysort(l,j);
    
    if(i<r)
        Mysort(i,r);
}

int n;

S main() {
    fr(n);
    
    for(int i(1);i<=n;++i)
        fr(a[i]);

    Mysort(1,n);

    for(int i(1);i<=n;++i)
        fw(a[i],0);

    Heriko Deltana;
}

「并查集」

仅使用了路径压缩。

UPD 2022.1.23

CI MXX(2e5+1),NXX(10001);

int fa[NXX],n,m;

int Find(int x) {
    if(fa[x]!=x)
        fa[x]=Find(fa[x]);

    Heriko fa[x];
}

I void Uni(int x,int y) {
    int fx(Find(x)),fy(Find(y));

    if(fx!=fy)
        fa[fx]=fy;
}

S main() {
    fr(n),fr(m);

    for(int i(1);i<=n;++i)
        fa[i]=i;

    for(int i(1);i<=m;++i) {
        int x,y,z;
        fr(z),fr(x),fr(y);

        if(z==1)
            Uni(x,y);
        else {
            if(Find(x)==Find(y))
                puts("Y");
            else
                puts("N");
        }
    }

    Heriko Deltana;
}

「线性筛」

这里是按照洛谷模板来写的,不过平时用不着询问部分,主要是 Es 函数。

UPD 2022.1.23

CI MXX(1e8+1);

int n,prime[MXX],cnt,q;

bool nopr[MXX];

I void Es() {
    nopr[1]=1;

    for(int i(2);i<=n;++i) {
        if(!nopr[i])
            prime[++cnt]=i;

        for(int j(1);j<=cnt and prime[j]*i<=n;++j) {
            nopr[i*prime[j]]=1;

            if(i%prime[j]==0)
                break;
        }
    }
}

S main() {
    fr(n),fr(q);
    Es();

    while(q--) {
        int x;
        fr(x);
        fw(prime[x],1);
    }

    Heriko Deltana;
}

「堆」

一般来说,都直接用 priority_queue.

UPD 2022.1.23

priority_queue< int,vector<int>,greater<int> > q;

int n;

S main() {
    fr(n);

    while(n--) {
        int opt,x;
        fr(opt);

        if(opt==1)
            fr(x),q.push(x);
        else if(opt==2)
            fw(q.top(),1);
        else
            q.pop();
    }

    Heriko Deltana;
}

「单调栈」

UPD 2022.1.23

CI MXX(3e6+1);

int n,a[MXX],f[MXX],stak[MXX],top;

S main() {
    fr(n);

    for(int i(1);i<=n;++i)
        fr(a[i]);

    for(int i(n);i>=1;--i) {
        while(top and a[stak[top]]<=a[i])
            --top;

        f[i]=top?stak[top]:0;
        stak[++top]=i;
    }

    for(int i(1);i<=n;++i)
        fw(f[i],0);
    
    Heriko Deltana;
}

「快速幂」

2021.12.25 更新了那行 x%=p,调了三天 ODT 居然是这里爆了……我从来没写过这,于是加上。

UPD 2022.1.23

I LL FstPow(LL x,LL y,LL p) {
    LL res(1);
    x%=p;

    while(y) {
        if(y&1)
            (res*=x)%=p;

        (x*=x)%=p;
        y>>=1;
    }

    Heriko res;
}

「单调队列」

第一个循环是求区间最小值,后者则为最大值。

UPD 2022.1.23

CI MXX(1e6+1);

int n,k,a[MXX],qmin[MXX],qmax[MXX],hd(1),tl;

S main() {
    fr(n),fr(k);

    for(int i(1);i<=n;++i)
        fr(a[i]);

    for(int i(1);i<=n;++i) {
        while(hd<=tl and a[qmin[tl]]>=a[i])
            --tl;

        qmin[++tl]=i;

        while(qmin[hd]<=i-k)
            ++hd;

        if(i>=k)
            fw(a[qmin[hd]],0);
    }

    puts("");
    hd=1,tl=0;
    
    for(int i(1);i<=n;++i) {
        while(hd<=tl and a[qmax[tl]]<=a[i])
            --tl;

        qmax[++tl]=i;

        while(qmax[hd]<=i-k)
            ++hd;

        if(i>=k)
            fw(a[qmax[hd]],0);
    }

    Heriko Deltana;
}

「最小生成树」

UPD 2022.1.23

「Prim」

因为没写挂了(?)暂时咕了

「Kruskal」

CI MXX(2e5+5),NXX(5001);

struct Node {
    int x,y,z;

    I bool operator < (const Node &co) const {
        Heriko z<co.z;
    }
}

r[MXX<<1];

int fa[NXX],n,m,ans,k;

int Find(int x) {
    if(fa[x]!=x)
        fa[x]=Find(fa[x]);

    Heriko fa[x];
}

I void Uni(int x,int y,int z) {
    int fx(Find(x)),fy(Find(y));

    if(fx!=fy) {
        fa[fx]=fy;
        ++k;
        ans+=z;
    }
}

S main() {
    fr(n),fr(m);

    for(int i(1);i<=n;++i)
        fa[i]=i;

    for(int i(1);i<=m;++i)
        fr(r[i].x),fr(r[i].y),fr(r[i].z);

    std::sort(r+1,r+1+m);

    for(int i(1);i<=m;++i) {
        Uni(r[i].x,r[i].y,r[i].z);

        if(k==n-1)
            break;
    }

    if(k==n-1)
        fw(ans,1);
    else
        puts("orz");

    Heriko Deltana;
}

「字符串哈希」

「单哈希+自然溢出」

UPD 2022.1.23

#define LL unsigned long long

const LL b(211),prime(19260817);

LL h[10015];

char s[10015];

int n,ans=1;

I LL hso(char x[]) {
    int lx=strlen(x);
    LL t=0;

    for(int i=0;i<lx;i++)
        t=(t*b+(LL)x[i])+prime;

    Heriko t;
}
S main() {
    fr(n);

    for(int i=1;i<=n;i++) {
        scanf("%s",s);
        h[i]=hso(s);
    }

    sort(h+1,h+1+n);

    for(int i=1;i<n;i++)
        if(h[i]!=h[i+1])
            ans++;

    fw(ans,1);

    Heriko Deltana;
}

「双哈希」

UPD 2022.1.23

CI MXX(1501),NXX(10005),MOD1(19260817),MOD2(998244353);

int n;

char s[MXX];

namespace Hash {
    #define ULL unsigned long long

    struct Node {
        ULL h1,h2;

        I bool operator < (const Node &co) const {
            Heriko (h1==co.h1)?(h2<co.h2):(h1<co.h1);
        }

        I bool operator != (const Node &co) const {
            Heriko !((h1==co.h1)&(h2==co.h2));
        }
    }

    a[NXX];

    I void GetHash1(int pos,char s[]) {
        int len(strlen(s));
        ULL tmp(0);

        for(int i(0);i<len;++i)
            tmp=(tmp*255+s[i])%MOD1;

        a[pos].h1=tmp;
    }

    I void GetHash2(int pos,char s[]) {
        int len(strlen(s));
        ULL tmp(0);

        for(int i(0);i<len;++i)
            tmp=(tmp*255+s[i])%MOD2;

        a[pos].h2=tmp;
    }

    I void GetHash(int pos,char s[]) {
        GetHash1(pos,s);
        GetHash2(pos,s);
    }

    I void Solve() {
        sort(a+1,a+1+n);
        int cnt(0);

        for(int i(1);i<=n;++i)
            if(a[i]!=a[i-1] or i==1)
                a[++cnt]=a[i];

        fw(cnt,1);

        exit(0);
    }
}

S main() {
    fr(n);

    for(int i(1);i<=n;++i) {
        scanf("%s",s+1);
        Hash::GetHash(i,s+1);
    }

    Hash::Solve();

    Heriko Deltana;
}

「单端最短路」

「Dijkstra」

UPD 2022.1.23

CI MXX(5e5+1),NXX(1e5+1);

struct node {
    int nex,to,val;
}

r[MXX];

int cnt,head[NXX];

I void Add(int x,int y,int z) {
    r[++cnt]=(node){head[x],y,z};
    head[x]=cnt;
}

struct co {
    int dis,id;

    I bool operator < (const co &x) const {
        Heriko x.dis<dis;
    }
};

priority_queue<co> q;

int dis[NXX],n,m,s;

bool vis[MXX];

I void Dijkstra() {
    dis[s]=0;
    q.push((co){0,s});

    while(q.size()) {
        int x(q.top().id);
        q.pop();

        if(vis[x])
            continue;

        vis[x]=1;

        for(int i(head[x]);i;i=r[i].nex) {
            int y(r[i].to);

            if(dis[y]>dis[x]+r[i].val) {
                dis[y]=dis[x]+r[i].val;

                if(!vis[y])
                    q.push((co){dis[y],y});
            }
        }
    }
}

S main()
{
    fr(n),fr(m),fr(s);
    mst(dis,0x7f);
    dis[0]=0;

    for(int i(1);i<=m;++i) {
        int x,y,z;
        fr(x),fr(y),fr(z);
        Add(x,y,z);
    }

    Dijkstra();

    for(int i(1);i<=n;++i)
        fw(dis[i],0);

    Heriko Deltana;
} 

「树状数组」

「单点修改区间询问」

UPD 2022.1.23

CI MXX(5e5+1);

#define lowbit(x) (x&(-x))

LL n,t[MXX],a[MXX],m;

I void Modify(int x,int v) {
    while(x<=n)
        t[x]+=v,x+=lowbit(x);
}

I LL Query(int x) {
    int res(0);
    
    while(x)
        res+=t[x],x-=lowbit(x);
        
    Heriko res;
}

S main() {
    fr(n),fr(m);

    for(int i(1);i<=n;++i)
        fr(a[i]);

    for(int i(1);i<=n;++i)
        Modify(i,a[i]);

    while(m--) {
        int opt,l,r;
        fr(opt),fr(l),fr(r);

        if(opt==1)
            Modify(l,r);
        else
            fw(Query(r)-Query(l-1),1);
    }

    Heriko Deltana;
}

「区间修改单点询问」

UPD 2022.1.23

#define lowbit(x) ((x)&(-x))

CI MXX(5e5+1);

int n,m,t[MXX],a[MXX];

I void Add(int x,int val) {
    while(x<=n)
        t[x]+=val,x+=lowbit(x);
}

I int Query(int x) {
    int res(0);

    while(x)
        res+=t[x],x-=lowbit(x);

    Heriko res;
} 

S main() {
    fr(n),fr(m);

    for(int i(1);i<=n;++i)
        fr(a[i]);

    for(int i(1);i<=n;++i)
        Add(i,a[i]-a[i-1]);

    while(m--) {
        int opt,x,y,z;
        fr(opt);

        if(opt==1) {
            fr(x),fr(y),fr(z);
            Add(x,z);
            Add(y+1,-z);
        }
        else {
            fr(x);
            fw(Query(x),1);
        }
    }

    Heriko Deltana;
}

「乘法逆元」

UPD 2022.1.23

CI MXX(3e6+1);

LL inv[MXX],n,m;

S main() {
    fr(n),fr(m);
    inv[1]=1;

    for(int i(2);i<=n;++i)
        inv[i]=m-(m/i)*inv[m%i]%m;
    
    for(int i(1);i<=n;++i)
        fw(inv[i],1);

    Heriko Deltana;
}

「高精度」

UPD 2022.1.23

CI MXX(105);

struct Pic {
    int num[MXX],sz;

    Pic() {
        mst(num,0);
        sz=1;
    }

    I void Clear() {
        mst(num,0);
        sz=1;
    }

    /*---- int * Pic ----*/

    I Pic operator * (const int &co) const {
        Pic res;
        res.sz=sz;

        for(int i(1);i<=sz;++i)
            res.num[i]=num[i]*co;

        for(int i(1);i<=sz;++i)
            res.num[i+1]+=(res.num[i]/10),res.num[i]%=10;

        while(res.num[res.sz+1]) {
            ++res.sz;
            res.num[res.sz+1]+=(res.num[res.sz]/10);
            res.num[res.sz]%=10;
        }

        Heriko res;
    }

    /*---- Pic * Pic ----*/

    I Pic operator * (const Pic &co) const {
        Pic res;
        res.sz=co.sz+sz;

        for(int i(1);i<=sz;++i)
            for(int j(1);j<=co.sz;++j) {
                res.num[i+j-1]+=(num[i]*co.num[j]);
                res.num[i+j]+=(res.num[i+j-1]/10);res.num[i+j-1]%=10;
            }

        while(!res.num[res.sz] and res.sz>1)
            --res.sz;

        Heriko res;
    }

    /*---- Pic + Pic ----*/

    I Pic operator + (const Pic &co) const {
        Pic res;
        res.sz=sz+2;

        for(int i(1);i<=sz;++i) {
            res.num[i]+=num[i]+co.num[i];

            if(res.num[i]>10)
                ++res.num[i+1],res.num[i]%=10;
        }

        while(!res.num[res.sz] and res.sz>1)
            --res.sz;

        Heriko res;
    }

    /*---- Pic - Pic ----*/

    /*Need to ensure *this > co*/

    I Pic operator - (const Pic &co) const {
        Pic res;
        res.sz=sz;

        for(int i(1);i<=sz;++i) {
            res.num[i]+=num[i]-co.num[i];

            if(res.num[i]<0)
                --res.num[i+1],res.num[i]+=10;
        }

        while(!res.num[res.sz] and res.sz>1)
            --res.sz;

        Heriko res;
    }

    /*---- Pic>>1 ----*/

    I void RightShift() {
        for(int i(sz);i;--i) {
            if(num[i]&1)
                num[i-1]+=10;

            num[i]>>=1;
        }

        while(!num[sz] and sz>1)
            --sz;
    }

    /*---- Pic < Pic ----*/

    I bool operator < (const Pic &co) const {
        if(sz!=co.sz)
            Heriko sz<co.sz;

        for(int i(sz);i;--i)
            if(num[i]!=co.num[i])
                Heriko num[i]<co.num[i];

        Heriko Deltana;
    }

    /*---- Pic > Pic ----*/

    I bool operator > (const Pic &co) const {
        if(sz!=co.sz)
            Heriko sz>co.sz;

        for(int i(sz);i;--i)
            if(num[i]!=co.num[i])
                Heriko num[i]>co.num[i];

        Heriko Deltana;
    }

    /*---- Pic <= Pic ----*/

    I bool operator <= (const Pic &co) const {
        Heriko !((*this)>co);
    }

    /*---- Pic >= Pic ----*/

    I bool operator >= (const Pic &co) const {
        Heriko !((*this)<co);
    }

    /*---- Pic == Pic ----*/

    I bool operator == (const Pic &co) const {
        Heriko (!((*this)>co))&(!((*this)<co));
    }

    /*---- Pic Input (char[] -> Pic) ----*/

    I void Into(char s[]) {
        sz=strlen(s+1);

        for(int i(1);i<=sz;++i)
            num[i]=s[sz-i+1]-'0';
    }

    /*---- Pic == 0 ? ----*/

    I bool Zero() {
        Heriko (sz==1)&(num[1]==0);
    }

    /*---- Pic Output ----*/

    I void fw() {
        for(int i(sz);i;--i)
            putchar(num[i]+'0'); putchar(' ');
    }
}

n,m;

「线段树」

UPD 2022.1.23

这里只放了个区间加和区间改,其它东西改一改就有了。

template<typename J>
I J Hmax(const J &x,const J &y) {
    Heriko x>y?x:y;
}

const LL MXX(1e6+1),INF(1e12);

int n,q;

struct Node {
    int l,r;LL mx,tg1,tg2;
}

t[MXX<<2];

I void Pushup(int x) {
    t[x].mx=Hmax(t[lc(x)].mx,t[rc(x)].mx);
}

I void Pushdown(int x) {
    if(t[x].tg2!=INF) {
        t[lc(x)].tg1=0;
        t[lc(x)].tg2=t[x].tg2;
        t[lc(x)].mx=t[x].tg2;
        t[rc(x)].tg1=0;
        t[rc(x)].tg2=t[x].tg2;
        t[rc(x)].mx=t[x].tg2;
        t[x].tg2=INF;
    }

    if(t[x].tg1) {
        t[lc(x)].tg1+=t[x].tg1;
        t[lc(x)].mx+=t[x].tg1;
        t[rc(x)].tg1+=t[x].tg1;
        t[rc(x)].mx+=t[x].tg1;
        t[x].tg1=0;
    }
}

void Build(int x,int l,int r) {
    t[x].l=l,t[x].r=r;
    t[x].mx=t[x].tg1=0;
    t[x].tg2=INF;

    if(l==r) {
        fr(t[x].mx);

        Heriko;
    }

    int mid((l+r)>>1);
    Build(lc(x),l,mid);
    Build(rc(x),mid+1,r);
    Pushup(x);
}

void ModifyAdd(int x,int lx,int rx,LL v) {
    if(lx<=t[x].l and t[x].r<=rx) {
        t[x].tg1+=v;t[x].mx+=v;

        Heriko;
    }

    Pushdown(x);
    int mid((t[x].l+t[x].r)>>1);

    if(lx<=mid)
        ModifyAdd(lc(x),lx,rx,v);
    
    if(rx>mid)
        ModifyAdd(rc(x),lx,rx,v);

    Pushup(x);
}

void ModifyChange(int x,int lx,int rx,LL v) {
    if(lx<=t[x].l and t[x].r<=rx) {
        t[x].tg1=0;t[x].tg2=v;t[x].mx=v;

        Heriko;
    }

    Pushdown(x);
    int mid((t[x].l+t[x].r)>>1);

    if(lx<=mid)
        ModifyChange(lc(x),lx,rx,v);
    
    if(rx>mid)
        ModifyChange(rc(x),lx,rx,v);

    Pushup(x);
}

LL Query(int x,int lx,int rx) {
    if(lx<=t[x].l and t[x].r<=rx)
        Heriko t[x].mx;

    LL res(-INF);
    int mid((t[x].l+t[x].r)>>1);
    Pushdown(x);

    if(lx<=mid)
        res=Hmax(Query(lc(x),lx,rx),res);
    
    if(rx>mid)
        res=Hmax(Query(rc(x),lx,rx),res);

    Heriko res;
}

S main() {
    fr(n),fr(q);
    Build(1,1,n);

    while(q--) {
        int opt,l,r;LL x;
        fr(opt),fr(l),fr(r);

        if(opt==1)
            fr(x),ModifyChange(1,l,r,x);
        else if(opt==2)
            fr(x),ModifyAdd(1,l,r,x);
        else
            fw(Query(1,l,r),1);
    }
    
    Heriko Deltana;
}

「主席树」

UPD 2022.2.20

CI MXX(1e5+1);

int n,q,lc[MXX<<5],rc[MXX<<5],sum[MXX<<5],t[MXX],a[MXX],b[MXX],id;

int Build(int l,int r) {
    int x(++id),mid((l+r)>>1);

    if(l<r) {
        lc[x]=Build(l,mid);
        rc[x]=Build(mid+1,r);
    }

    Heriko x;
}

int Insert(int pre,int l,int r,int v) {
    int x(++id),mid((l+r)>>1);
    lc[x]=lc[pre],rc[x]=rc[pre],sum[x]=sum[pre]+1;

    if(l<r) {
        if(v<=mid)
            lc[x]=Insert(lc[pre],l,mid,v);
        else
            rc[x]=Insert(rc[pre],mid+1,r,v);
    }

    Heriko x;
}

int Query(int x,int y,int l,int r,int v) {
    if(l>=r)
        Heriko l;

    int nw(sum[lc[y]]-sum[lc[x]]),mid((l+r)>>1);

    if(nw>=v)
        Heriko Query(lc[x],lc[y],l,mid,v);
    else
        Heriko Query(rc[x],rc[y],mid+1,r,v-nw);
}

S main() {
    fr(n),fr(q);

    for(int i(1);i<=n;++i)
        fr(a[i]),b[i]=a[i];

    sort(b+1,b+1+n);
    int nl(unique(b+1,b+1+n)-b-1);

    for(int i(1);i<=n;++i)
        a[i]=lower_bound(b+1,b+1+nl,a[i])-b;

    t[0]=Build(1,nl);

    for(int i(1);i<=n;++i)
        t[i]=Insert(t[i-1],1,nl,a[i]);

    while(q--) {
        int l,r,k;
        fr(l),fr(r),fr(k);
        fw(b[Query(t[l-1],t[r],1,nl,r-l+1-k+1)],1);//求区间第 K 大
        fw(b[Query(t[l-1],t[r],1,nl,k)],1);//求区间第 K 小
    }

    Heriko Deltana;
}

「ST表」

UPD 2022.1.23


template<typename J>
I J Hmax(const J &x,const J &y) {
    Heriko x>y?x:y;
}

CI MXX(1e5+1);

LL a[MXX][22];

int n,m;

I LL Query(int l,int r) {
    int tmp(std::log2(r-l+1));

    Heriko Hmax(a[l][tmp],a[r-(1<<tmp)+1][tmp]);
}

S main() {
    fr(n),fr(m);

    for(int i(1);i<=n;++i)
        fr(a[i][0]);

    for(int lg(1);lg<=21;++lg)
        for(int i(1);i+(1<<lg)-1<=n;++i)
            a[i][lg]=Hmax(a[i][lg-1],a[i+(1<<(lg-1))][lg-1]);

    for(int i(1);i<=m;++i) {
        int l,r;
        fr(l),fr(r);
        fw(Query(l,r),1);
    }

    Heriko Deltana;
}

「三分法」

UPD 2022.1.23

template<typename J>
I J Habs(const J &x) {
    Heriko x<0?-x:x;
}

const double EPS(1e-7);

CI MXX(15);

int n;

double a[MXX],l,r;

double Solve(double x) {
    double res(0);

    for(int i(n);i>=0;--i)
        res*=x,res+=a[i];

    Heriko res;
}

S main() {
    fr(n);
    scanf("%lf%lf",&l,&r);

    for(int i(n);i>=0;--i)
        scanf("%lf",&a[i]);

    while(Habs(r-l)>=EPS) {
        double mid((l+r)/2);

        if(Solve(mid+EPS)>Solve(mid-EPS))
            l=mid;
        else
            r=mid;
    }

    printf("%.5lf\n",r);

    Heriko Deltana;
}

「KMP」

UPD 2022.1.23

CI MXX(1e6+1);

int lena,lenb,nex[MXX],kmp[MXX];

char a[MXX],b[MXX];

S main() {
    scanf("%s%s",a+1,b+1);
    lena=strlen(a+1),lenb=strlen(b+1);

    for(int i(2),j(0);i<=lenb;++i) {
        while(j>0 and b[i]!=b[j+1])
            j=nex[j];

        if(b[i]==b[j+1])
            ++j;

        nex[i]=j;
    }

    for(int i(1),j(0);i<=lena;++i) {
        while(j>0 and a[i]!=b[j+1])
            j=nex[j];

        if(a[i]==b[j+1])
            ++j;

        kmp[i]=j;
    }

    for(int i(1);i<=lena;++i)
        if(kmp[i]==lenb)
            fw(i-lenb+1,1);

    for(int i(1);i<=lenb;++i)
        fw(nex[i],0);

    Heriko Deltana;
}

「LCA」

「倍增」

UPD 2022.1.23

CI MXX(5e5+1);

int n,m,rt;

struct Node {
    int nex,to;
}

r[MXX<<1];

int cnt,head[MXX];

I void Add(int x,int y) {
    r[++cnt]=(Node){head[x],y};head[x]=cnt;
    r[++cnt]=(Node){head[y],x};head[y]=cnt;
}

int dep[MXX],f[MXX][35],lg[MXX];

I void PreLog() {
    for(int i(1);i<=n;++i)
        lg[i]=lg[i-1]+((1<<lg[i-1])==i);
}

void DFS(int x,int fa) {
    f[x][0]=fa;
    dep[x]=dep[fa]+1;
    
    for(int i(1);i<=lg[dep[x]];++i)
        f[x][i]=f[f[x][i-1]][i-1];
        
    for(int i(head[x]);i;i=r[i].nex)
        if(r[i].to!=fa)
            DFS(r[i].to,x);
}

I int LCA(int x,int y) {
    if(dep[x]<dep[y])
        swap(x,y);
    
    while(dep[x]>dep[y])
        x=f[x][lg[dep[x]-dep[y]]-1];
        
    if(x==y)
        Heriko x;
        
    for(int i(lg[dep[x]]-1);i>=0;--i)
        if(f[x][i]!=f[y][i])
            x=f[x][i],y=f[y][i];
            
    Heriko f[x][0];
}

S main() {
    fr(n),fr(m),fr(rt);
    
    for(int i(1);i<n;++i) {
        int x,y;
        fr(x),fr(y);
        Add(x,y);
    }
    
    PreLog();
    DFS(rt,0);
    
    for(int i(1);i<=m;++i) {
        int x,y;
        fr(x),fr(y);
        fw(LCA(x,y),1);
    }

    Heriko Deltana;
}

「树剖」

UPD 2022.1.23

CI MXX(500001);

struct Node {
    int nex,to;
}

r[MXX<<1];

int rcnt,head[MXX];

I void Add(int x,int y) {
    r[++rcnt]=(Node){head[x],y},head[x]=rcnt;
    r[++rcnt]=(Node){head[y],x},head[y]=rcnt;
}

int sz[MXX],son[MXX],top[MXX],fa[MXX],dep[MXX];

void DFS1(int x,int fath) {
    sz[x]=1,fa[x]=fath,dep[x]=dep[fath]+1;

    for(int i(head[x]);i;i=r[i].nex) {
        int y(r[i].to);

        if(y==fath)
            continue;

        DFS1(y,x);
        sz[x]+=sz[y];

        if(!son[x] or sz[son[x]]<sz[y])
            son[x]=y;
    }
}

void DFS2(int x,int nw) {
    top[x]=nw;

    if(son[x])
        DFS2(son[x],nw);

    for(int i(head[x]);i;i=r[i].nex) {
        int y(r[i].to);

        if(y==fa[x] or y==son[x])
            continue;

        DFS2(y,y);
    }
}

int n,m,s;

S main() {
    // Files();

    fr(n),fr(m),fr(s);

    for(int i(1);i<n;++i) {
        int x,y;
        fr(x),fr(y);
        Add(x,y);
    }

    DFS1(s,0);
    DFS2(s,s);

    for(int i(1);i<=m;++i) {
        int x,y;
        fr(x),fr(y);

        while(top[x]!=top[y]) {
            if(dep[top[x]]>=dep[top[y]])
                x=fa[top[x]];
            else
                y=fa[top[y]];
        }

        fw((dep[x]<dep[y])?x:y,1);
    }

    Heriko Deltana;
}

「矩阵加速」

UPD 2022.1.23

CI MOD(1e9+7);

int n,T;

struct Matrix {
    LL a[5][5];

    Matrix() {
        mst(a,0);
    }

    I void BuildB() {
        mst(a,0);
        a[1][1]=a[1][3]=a[2][1]=a[3][2]=1;
    }

    I void BuildA() {
        mst(a,0);
        a[1][1]=a[2][1]=a[3][1]=1;
    }

    I Matrix operator * (const Matrix &co) const {
        Matrix res;

        for(int k(1);k<=3;++k)
            for(int i(1);i<=3;++i)
                for(int j(1);j<=3;++j)
                    (res.a[i][j]+=(a[i][k]*co.a[k][j])%MOD)%=MOD;

        Heriko res;
    }
}

A,B;

I void MatrixFstPow(int x) {
    while(x) {
        if(x&1)
            A=A*B;

        B=B*B;
        x>>=1;
    }
}

S main() {
    fr(T);

    while(T--) {
        fr(n);

        if(n<=3)
            puts("1");
        else {
            A.BuildA(),B.BuildB();
            MatrixFstPow(n-1);
            fw((A.a[1][1]+MOD)%MOD,1);
        }
    }

    Heriko Deltana;
}

「SPFA判负环」

UPD 2022.1.23

CI MXX(3001),INF(0x3f3f3f3f);

int n,m,T;

struct Node {
    int nex,to,val;
}

r[MXX<<1];

int cnt,head[MXX];

I void Add(int x,int y,int z) {
    r[++cnt]=(Node){head[x],y,z};
    head[x]=cnt;
}

int co[MXX],dis[MXX];

bitset<MXX> vis;

I bool SPFA(int s) {
    queue<int> q;
    q.push(s);
    dis[s]=0,vis[s]=1,++co[s];

    while(q.size()) {
        int x(q.front());
        q.pop();
        vis[x]=0;

        for(int i(head[x]);i;i=r[i].nex) {
            int y(r[i].to);

            if(dis[y]>dis[x]+r[i].val) {
                dis[y]=dis[x]+r[i].val;

                if(!vis[y]) {
                    vis[y]=1;
                    q.push(y);
                    ++co[y];

                    if(co[y]>n)
                        Heriko Deltana;
                }
            }
        }
    }

    Heriko Romanno;
}

S main() {
    Files();

    fr(T);
    
    while(T--) {
        fr(n),fr(m);
        cnt=0,vis=0;
        mst(dis,0x3f),mst(co,0),mst(head,0);

        for(int i(1);i<=m;++i) {
            int x,y,z;
            fr(x),fr(y),fr(z);

            if(z>=0)
                Add(x,y,z),Add(y,x,z);
            else
                Add(x,y,z);
        }

        if(!SPFA(1))
            puts("YES");
        else
            puts("NO");
    }

    Heriko Deltana;
}

「矩阵快速幂」

UPD 2022.1.23

CI NXX(101),MXX(21),MOD(1e9+7);

struct Matrix {
    int n,m,a[MXX][MXX];

    Matrix() {
        n=m=0,mst(a,0);
    }

    I void Build() {
        for(int i(1);i<=m;++i)
            a[i][i]=1;
    }

    I Matrix operator * (const Matrix &co) const {
        Matrix res;
        res.n=n,res.m=co.m;

        for(int i(1);i<=n;++i)
            for(int k(1);k<=m;++k)
                for(int j(1);j<=co.m;++j)
                    (res.a[i][j]+=(1ll*a[i][k]*co.a[k][j])%MOD)%=MOD;

        Heriko res;
    }
}

ans;

int n,m;

I Matrix MFP(Matrix x,int y) {
    Matrix res;
    res.n=res.m=m;
    res.Build();

    while(y) {
        if(y&1)
            res=res*x;

        x=x*x;
        y>>=1;
    }

    Heriko res;
}

「AC自动机」

UPD 2022.1.23

CI MXX(1e6+5);

struct ACAM {
    int c[MXX][26],val[MXX],fail[MXX],cnt;
    queue<int> q;

    I void Insert(char s[]) {
        int len(strlen(s)),nw(0);

        for(int i(0);i<len;++i) {
            int v(s[i]-'a');

            if(!c[nw][v])
                c[nw][v]=++cnt;

            nw=c[nw][v];
        }

        ++val[nw];
    }

    I void Build() {
        for(int i(0);i<26;++i)
            if(c[0][i])
                fail[c[0][i]]=0,q.push(c[0][i]);

        while(q.size()) {
            int x(q.front());
            q.pop();

            for(int i(0);i<26;++i)
                if(c[x][i])
                    fail[c[x][i]]=c[fail[x]][i],q.push(c[x][i]);
                else
                    c[x][i]=c[fail[x]][i];
        }
    }

    I int Query(char s[]) {
        int len(strlen(s)),nw(0),res(0);

        for(int i(0);i<len;++i) {
            nw=c[nw][s[i]-'a'];

            for(int j(nw);j and ~val[j];j=fail[j])
                res+=val[j],val[j]=-1;
        }

        Heriko res;
    }
}

AC;

int n;

char s[MXX];

S main() {
    Files();

    fr(n);

    for(int i(1);i<=n;++i)
        scanf("%s",s),AC.Insert(s);

    AC.Build();

    scanf("%s",s);
    fw(AC.Query(s),1);

    Heriko Deltana;
}

「差分约束」

UPD 2022.1.23

CI MXX(5e3+5),INF(0x3f3f3f3f);

int n,m,T;

struct Node {
    int nex,to,val;
}

r[MXX<<1];

int cnt,head[MXX];

I void Add(int x,int y,int z) {
    r[++cnt]=(Node){head[x],y,z};
    head[x]=cnt;
}

int co[MXX],dis[MXX];

bitset<MXX> vis;

I bool SPFA(int s) {
    queue<int> q;
    q.push(s);
    mst(dis,0x3f);
    dis[s]=0,vis[s]=1,++co[s];

    while(q.size()) {
        int x(q.front());
        q.pop();
        vis[x]=0;

        for(int i(head[x]);i;i=r[i].nex) {
            int y(r[i].to);

            if(dis[y]>dis[x]+r[i].val) {
                dis[y]=dis[x]+r[i].val;

                if(!vis[y]) {
                    vis[y]=1;
                    q.push(y);
                    ++co[y];

                    if(co[y]>=n+1)
                        Heriko Deltana;
                }
            }
        }
    }

    Heriko Romanno;
}

S main() {
    Files();

    fr(n),fr(m);

    for(int i(1);i<=n;++i)
        Add(0,i,0);

    for(int i(1);i<=m;++i) {
        int x,y,z;
        fr(x),fr(y),fr(z);
        Add(y,x,z);
    }

    if(!SPFA(0))
        puts("NO");
    else
        for(int i(1);i<=n;++i)
            fw(dis[i],0);

    Heriko Deltana;
}

「欧拉路径」

UPD 2022.1.23

调了 \(\tt 114514\) 年,结果是答案栈开小了。

template<typename J>
I J Hmax(const J &x,const J &y) {
    Heriko x>y?x:y;
}

CI MXX(1e5+5);

int n,m,into[MXX],outo[MXX],lst[MXX],ans[MXX<<1],s,t,cnt;

vector< pair<int,int> > r[MXX];

bitset<(MXX<<1)> vis;

void DFS(int x) {
    for(int i(lst[x]);i<(int)r[x].size();i=Hmax(i+1,lst[x])) {
        int y(r[x][i].first),id(r[x][i].second);

        if(!vis[id]) {
            vis[id]=1;
            lst[x]=i+1;
            DFS(y);
        }
    }

    ans[++cnt]=x;
}

S main() {
    Files();

    fr(n),fr(m);

    for(int i(1);i<=m;++i) {
        int x,y;
        fr(x),fr(y);
        ++outo[x],++into[y];
        r[x].push_back(mkp(y,i));
    }

    int tot(0);
    
    for(int i(1);i<=n;++i)
        if(into[i]!=outo[i]) {
            ++tot;

            if(into[i]==outo[i]-1)
                s=i;
            if(into[i]==outo[i]+1)
                t=i;
        }

    if(tot!=0 and tot!=2) {
        puts("No");

        Heriko Deltana;
    }

    if(!tot)
        s=t=1;
    
    if(!s or !t) {
        puts("No");

        Heriko Deltana;
    }

    for(int i(1);i<=n;++i)
        sort(r[i].begin(),r[i].end());

    DFS(s);

    for(int i(cnt);i;--i)
        fw(ans[i],0);

    Heriko Deltana;
}

「康托展开」

UPD 2022.1.23

#define lowbit(x) ((x)&(-x))

CI MXX(1e6+1),MOD(998244353);

int n;

LL t[MXX];

I void Add(int x,LL v) {
    while(x<=n)
        t[x]+=v,x+=lowbit(x);
}

I LL Query(int x) {
    LL res(0);

    while(x)
        res+=t[x],x-=lowbit(x);

    Heriko res;
}

LL pw[MXX],ans;

S main() {
    Files();

    fr(n);

    for(int i(1);i<=n;++i)
        Add(i,1);

    pw[0]=1;

    for(int i(1);i<=n;++i)
        pw[i]=(pw[i-1]*i)%MOD;

    for(int i(1);i<=n;++i) {
        int x;
        fr(x);
        (ans+=((Query(x)-1)*pw[n-i])%MOD)%=MOD;
        Add(x,-1);
    }

    fw(ans+1,1);

    Heriko Deltana;
}

「威佐夫博弈」

UPD 2022.1.23

结论:若两堆物品的初始值为 \((n,m)\),且 \(m<n\),则使 \(z=n-m.\)

x=(LL)(((sqrt(5.0)+1.0)/2.0)*w);

\(m=x\),则先手必败,否则先手必胜。

LL n,m,w,x;

S main() {
    Files();

    fr(n),fr(m);

    if(n<m)
        swap(n,m);

    w=n-m;
    x=(LL)(((sqrt(5.0)+1.0)/2.0)*w);

    if(x==m)
        puts("0");
    else
        puts("1");

    Heriko Deltana;
}

「莫队」

UPD 2022.1.23

CI MXX(5e4+1);

int n,m,k,a[MXX],sqn;

LL ans[MXX],co[MXX],cnt;

struct Node {
    int l,r,id;

    I bool operator < (const Node &co) const {
        if(l/sqn!=co.l/sqn)
            Heriko l<co.l;

        if((l/sqn)&1)
            Heriko r<co.r;

        Heriko r>co.r;
    }
}

q[MXX];

I void Add(int x) {
    
}

I void Del(int x) {
    
}

S main() {
    Files();

    fr(n),fr(m),fr(k),sqn=sqrt(n);

    for(int i(1);i<=n;++i)
        fr(a[i]);

    for(int i(1);i<=m;++i)
        fr(q[i].l),fr(q[i].r),q[i].id=i;

    sort(q+1,q+1+m);

    int lx(1),rx(0);

    for(int i(1);i<=m;++i) {
        while(lx<q[i].l)
            Del(a[lx++]);

        while(lx>q[i].l)
            Add(a[--lx]);

        while(rx<q[i].r)
            Add(a[++rx]);

        while(rx>q[i].r)
            Del(a[rx--]);

        ans[q[i].id]=cnt;
    }

    for(int i(1);i<=m;++i)
        fw(ans[i],1);

    Heriko Deltana;
}

「vector 存图遍历模板」

UPD 2022.1.23

CI MXX(1e6+1),NXX(1e5+1);

bitset<NXX> vis;

vector<int> r[NXX];

int n,m;

void DFS(int x) {
    fw(x,0);
    vis[x]=1;
    int sz(r[x].size());

    for(int i(0);i<sz;++i)
        if(!vis[r[x][i]])
            DFS(r[x][i]);
}

I void BFS() {
    queue<int> q;
    q.push(1),vis[1]=1;

    while(q.size()) {
        int y(q.front());
        q.pop();
        fw(y,0);
        int sz(r[y].size());

        for(int i(0);i<sz;++i)
            if(!vis[r[y][i]])
                q.push(r[y][i]),vis[r[y][i]]=1;
    }
}

S main() {
    Files();

    fr(n),fr(m);

    for(int i(1);i<=m;++i) {
        int x,y;
        fr(x),fr(y);
        r[x].push_back(y);
    }

    for(int i(1);i<=n;++i)
        std::sort(r[i].begin(),r[i].end());

    DFS(1),puts("");
    vis=0;
    BFS(),puts("");

    Heriko Deltana;
}

「Dinic」

UPD 2022.1.23

template <typename J>
I J Hmin(const J &x,const J &y) {
    Heriko x<y?x:y;
}

CI MXX(5001),NXX(201),INF(998244353);

struct Node {
    int nex,to;
    LL val;
}

r[MXX<<1];

int cnt(1),head[NXX],now[NXX],n,m,s,t;

I void Add(int x,int y,LL z) {
    r[++cnt]=(Node){head[x],y,z},head[x]=cnt;
    r[++cnt]=(Node){head[y],x,0},head[y]=cnt;
}

LL dis[NXX],ans;

bitset<NXX> vis;

I bool BFS() {
    mst(dis,0);
    queue<int> q;
    q.push(s);
    dis[s]=1,now[s]=head[s];

    while(q.size()) {
        int x(q.front());
        q.pop();

        for(int i(head[x]);i;i=r[i].nex) {
            if(r[i].val and !dis[r[i].to]) {
                int y(r[i].to);
                q.push(y);
                now[y]=head[y],dis[y]=dis[x]+1;

                if(y==t)
                    Heriko Romanno;
            }
        }
    }

    Heriko Deltana;
}

LL Dinic(int x,LL flow) {
    if(x==t)
        Heriko flow;

    LL rst(flow),k;

    for(int i(now[x]);i and rst;i=r[i].nex) {
        int y(r[i].to);

        if(r[i].val and dis[y]==dis[x]+1) {
            k=Dinic(y,Hmin(rst,r[i].val));

            if(!rst)
                Heriko flow;

            if(!k)
                dis[y]=0;

            r[i].val-=k,r[i^1].val+=k,rst-=k;
        }

        now[x]=i;
    }

    Heriko flow-rst;
}

S main() {
    // Files();

    fr(n),fr(m),fr(s),fr(t);

    for(int i(1);i<=m;++i) {
        int x,y;
        LL z;
        fr(x),fr(y),fr(z);
        Add(x,y,z);
    }

    LL flow(0);

    while(BFS())
        while((flow=Dinic(s,INF)))
            ans+=flow;

    fw(ans,1);

    Heriko Deltana;
}

「Tarjan求强连通分量」

UPD 2022.1.23

template <typename J>
I J Hmin(const J &x,const J &y) {
    Heriko x<y?x:y;
}

CI MXX(100001),NXX(10001);

struct Node {
    int nex,to;    
}

r[MXX];

int rcnt,head[NXX];

I void Add(int x,int y) {
    r[++rcnt]=(Node){head[x],y};
    head[x]=rcnt;
}

int dfn[NXX],low[NXX],cnt,stak[NXX],top,tot,c[NXX];

bitset<NXX> vis;

vector<int> v[NXX];

void Tarjan(int x) {
    dfn[x]=low[x]=++cnt;
    stak[++top]=x,vis[x]=1;

    for(int i(head[x]);i;i=r[i].nex) {
        int y(r[i].to);

        if(!dfn[y])
            Tarjan(y),low[x]=Hmin(low[x],low[y]);
        else if(vis[y])
            low[x]=Hmin(low[x],dfn[y]);
    }

    if(dfn[x]==low[x]) {
        ++tot;
        int tmp(0);

        while(tmp!=x) {
            tmp=stak[top--];
            vis[tmp]=0;
            c[tmp]=tot;
            v[tot].push_back(tmp);
        }
    }
}

int n,m;

S main() {
    // Files();

    fr(n),fr(m);

    for(int i(1);i<=m;++i) {
        int x,y;
        fr(x),fr(y);
        Add(x,y);
    }

    for(int i(1);i<=n;++i)
        if(!dfn[i])
            Tarjan(i);

    fw(tot,1);

    for(int i(1);i<=n;++i) {
        int x(c[i]);        

        if(vis[x])
            continue;

        vis[x]=1;
        std::sort(v[x].begin(),v[x].end());
        int sz(v[x].size());

        for(int j(0);j<sz;++j)
            fw(v[x][j],0);

        puts("");
    }

    Heriko Deltana;
}

「珂朵莉树」

直接把我 CF896C 的代码拿过来了。

UPD 2022.1.23


I LL FstPow(LL x,LL y,LL p) {
    LL res(1);
    x%=p;

    while(y) {
        if(y&1)
            (res*=x)%=p;

        (x*=x)%=p;
        y>>=1;
    }

    Heriko res;
}//其实这个快速幂没啥用,只是下面的 Query 的时候有用到,和 ODT 本身关系不大。

struct Node {
    LL l,r;
    mutable LL v;

    Node(LL l,LL r=0,LL v=0) : l(l),r(r),v(v) {}

    I bool operator < (const Node &co) const {
        Heriko l<co.l;
    }
};

set<Node> s;

I auto Split(LL pos) {
    auto it(s.lower_bound(Node(pos)));

    if(it!=s.end() and it->l==pos)
        Heriko it;

    --it;

    if(it->r<pos)
        Heriko s.end();

    LL l(it->l),r(it->r),v(it->v);
    s.erase(it);
    s.insert(Node(l,pos-1,v));

    Heriko s.insert(Node(pos,r,v)).first;
}

I void Assign(LL l,LL r,LL x) {
    auto itr(Split(r+1)),itl(Split(l));
    s.erase(itl,itr);
    s.insert(Node(l,r,x));
}

I void Add(LL l,LL r,LL x) {
    auto itr(Split(r+1)),itl(Split(l));

    for(auto it(itl);it!=itr;++it)
        it->v+=x;
}

struct Rank {
    LL val,cnt;

    Rank(LL val,LL cnt) : val(val),cnt(cnt) {}

    I bool operator < (const Rank &co) const {
        Heriko val<co.val;
    }
};

I LL QueryRank(LL l,LL r,LL x) {
    auto itr(Split(r+1)),itl(Split(l));
    vector<Rank> v;
    
    for(auto it(itl);it!=itr;++it)
        v.push_back(Rank(it->v,it->r-it->l+1));

    sort(v.begin(),v.end());
    LL i(0);

    for(;i<(LL)v.size();++i)
        if(v[i].cnt<x)
            x-=v[i].cnt;
        else
            Heriko v[i].val;

    Heriko v[i].val;
}

I LL QueryVal(LL l,LL r,LL x,LL y) {
    auto itr(Split(r+1)),itl(Split(l));
    LL res(0);
    
    for(auto it(itl);it!=itr;++it)
        res=(res+FstPow(it->v,x,y)*(it->r-it->l+1)%y)%y;

    Heriko res;
}

「平面最近点对」

\(O(n \log^2 n)\) 的做法。

UPD 2022.1.23

template<typename J>
I J Hmin(const J &x,const J &y) {
    Heriko x<y?x:y;
}

CI MXX(2e5+1);
const double INF(1e12);

I bool CMP(const pair<double,double> &a,const pair<double,double> &b) {
    Heriko a.second<b.second;
}

I double Dist(const pair<double,double> &a,const pair<double,double> &b) {
    Heriko sqrt((long double)(a.first-b.first)*(a.first-b.first)+(long double)(a.second-b.second)*(a.second-b.second));
}

int n;

pair<double,double> a[MXX],tmp[MXX];

double Merge(int l,int r) {
    if(l==r)
        Heriko INF;

    int mid((l+r)>>1),top(0);
    double dis(INF);
    dis=Hmin(Merge(l,mid),Merge(mid+1,r));

    for(int i(l);i<=r;++i)
        if(fabs(a[mid].first-a[i].first)<dis)
            tmp[++top]=a[i];

    std::sort(tmp+1,tmp+1+top,CMP);

    for(int i(1);i<=top;++i)
        for(int j(i+1);j<=top;++j) {
            if(tmp[j].second-tmp[i].second>=dis)
                break;
            
            dis=Hmin(dis,Dist(tmp[i],tmp[j]));
        }
            

    Heriko dis;
}

S main() {
    Files();

    fr(n);

    for(int i(1);i<=n;++i)
        scanf("%lf%lf",&a[i].first,&a[i].second);

    std::sort(a+1,a+1+n);
    double ans(Merge(1,n));
    printf("%.4lf",ans);

    Heriko Deltana;
}
posted @ 2021-10-02 21:56  HerikoDeltana  阅读(99)  评论(0编辑  收藏  举报