【/ɔɪ:/】模板

前言

这篇文章仅用于存放各种模板,不写注释,具体原理请在 /ɔɪ:/ 查看。

正在汇总中……

缺省源

主要 tuple 是 C++17 的东西但是 CCF 的测评机可以编译通过,dSir 的似乎就不行。

缺省源
#include<bits/stdc++.h>
using namespace std;
#define dbg(x) cerr<<#x<<':'<<(x)<<' '
#define dbe(x) cerr<<#x<<':'<<(x)<<endl
#define eb emplace_back
using ll=long long;
using vi=vector<int>;
using vl=vector<ll>;
using tp=tuple<int,int>;
int main(){
    cin.tie(0)->sync_with_stdio(0);
    
    return 0;
}

对拍

这是 Linux 下的对拍。首先我们需要四个程序:code.cpp,bl.cpp,sj.cpp,dp.cpp。前两个一个放自己的程序一个放暴力程序,第三个放造数据的程序(每造一组数据 dp.cpp 都会给它传入一个数,需要将这个数设置为随机种子),都不用写文件输入输出。dp.cpp 里要写这个东西:

对拍
#include<bits/stdc++.h>
using namespace std;
int main(){
    system("g++ -O2 code.cpp -o code -Wall -static -std=c++14");
    system("g++ -O2 bl.cpp -o bl -Wall -static -std=c++14");
    system("g++ -O2 sj.cpp -o sj -Wall -static -std=c++14");
    int t=1e8;
    for(int i=1;i<=t;i++){
        FILE *fp=fopen("seed.in","w");
        fprintf(fp,"%d",i);
        fclose(fp);
        system("./sj < seed.in > dp.in");
        system("./bl < dp.in > dp.ans");
        double st=clock();
        system("./code < dp.in > dp.out");
        double ed=clock();
        cout<<i<<" "<<ed-st<<" ms\n";
        if(system("diff dp.out dp.ans")){
            cout<<"WA\n";
            break;
        }
    }
    return 0;
}

离散化

C++
vi lsh;
//lsh.eb(someting);
sort(lsh.begin(),lsh.end());
lsh.resize(unique(lsh.begin(),lsh.end())-lsh.begin());
auto LSH=[&](int x){
    return lower_bound(lsh.begin(),lsh.end(),x)-lsh.begin();
};

STL

unordered_map

重定义哈希函数:

unordered_map
struct S{
    unsigned int x,y;
    bool operator==(S a)const{
        return x==a.x&&y==a.y;
    }
};
struct SHash{
    ull operator()(S a)const{
        return (a.x<<32)+a.y;
    }
};
unordered_map<S,int,SHash>ma;

数据结构

树状数组

bit
struct bit{
    int n;
    vi c;
    bit(){}
    bit(int n):n(n){
        c.resize(n+1);
    }
    void add(int x,int d){
        while(x<=n)c[x]+=d,x+=x&-x;
    }
    int cha(int x){
        int ans=0;
        while(x)ans+=c[x],x-=x&-x;
        return ans;
    }
    int ef(int k){
        int x=1<<(31-__builtin_clz(n)),sc=0;
        while((x&-x)>1){
            if(x>n||c[x]>=k)sc=x,x-=(x&-x)>>1;
            else k-=c[x],x+=(x&-x)>>1;
        }
        return k-c[x]?sc:x;
    }
};

线段树

自己敲,看什么模板。

字符串

最小表示法

最小表示法
int n=s.size();
s=s+s;
int i=0,j=0,k=0;
while(i<n&&j<n&&k<n){
    if(i==j)j++;
    if(s[i+k]==s[j+k])k++;
    else if(s[i+k]<s[j+k])j=j+k+1,k=0;
    else i=i+k+1,k=0;
}

manacher

manacher
vi d(n,1);
int p=0,r=1;
for(int i=1;i<n;i++){
    if(i<r)d[i]=min(d[p-(i-p)],r-i+1);
    while(i-d[i]>=0&&i+d[i]<n&&s[i-d[i]]==s[i+d[i]])d[i]++;
    if(r<i+d[i]-1)r=i+d[i]-1,p=i;
}

Z Algorithm

Z算法
vi z(n,0);
int l=0,r=0;
for(int i=1;i<n;i++){
    if(i<r)z[i]=min(z[i-l],r-i+1);
    while(i+z[i]<n&&s[z[i]]==s[i+z[i]])z[i]++;
    if(i+z[i]-1>r)r=i+z[i]-1,l=i;
}
z[0]=n;

KMP

KMP
vi pi(n+1);
for(int i=2;i<=n;i++){
    int j=pi[i-1];
    while(j>0&&s[j+1]!=s[i])j=pi[j];
    j+=(s[j+1]==s[i]);
    pi[i]=(j==i?0:j);
}

数学&数论

快速幂

快速幂
int ksm(int a,int b){
    int ans=1;
    while(b){
        if(b&1)ans=(ll)ans*a%P;
        a=(ll)a*a%P;
        b>>=1;
    }
    return ans;
}

线性筛

线性筛
vi prm,v(N+1);
for(int i=2;i<=N;i++){
    if(v[i]==0)v[i]=i,prm.emplace_back(i);
    for(auto p:prm){
        if(p*i>N||v[i]<p)break;
        v[i*p]=p;
    }
}

EXGCD

做了些许简化。

C++
function<int(int,int,ll&,ll&)>exgcd=[&](int a,int b,ll& x,ll& y){
    if(b==0){x=1,y=0;return a;}
    int d=exgcd(b,a%b,y,x);
    y-=a/b*x;
    return d;
};

线性组合计数(线性求逆元)

功能有快速幂,求 inv[i],fct[i],invfct[i],求 $\binom{n}{m}$ 和 $\binom{n}{a_1,a_2,\dots ,a_k}$。放在main函数外面,记得使用前要调用init初始化。

线性求逆元
const int P=1e9+9;
namespace modint{
    vi fct,inv,invfct;
    int ksm(int a,int b){
        int ans=1;
        while(b){
            if(b&1)ans=(ll)ans*a%P;
            a=(ll)a*a%P;
            b>>=1;
        }
        return ans;
    }
    void init(int n){
        fct.resize(n+1);
        inv.resize(n+1);
        invfct.resize(n+1);
        fct[0]=1;
        for(int i=1;i<=n;i++){
            fct[i]=(ll)fct[i-1]*i%P;
        }
        invfct[n]=ksm(fct[n],P-2);
        for(int i=n;i>=1;i--){
            inv[i]=(ll)fct[i-1]*invfct[i]%P;
            invfct[i-1]=(ll)i*invfct[i]%P;
        }
    }
    int binom(int n,int m){
        return (ll)fct[n]*invfct[m]%P*invfct[n-m]%P;
    }
    int binom(int n,vi m){
        int ans=fct[n];
        for(auto v:m){
            ans=(ll)ans*invfct[v]%P;
        }
        return ans;
    }
}
using namespace modint;

整数分块

整数分块
int sum=0;
for(int l=1,r;l<=n;l=r+1){
    r=n/(n/l);
    sum+=(r-l+1)*(n/l);
}

矩阵乘法

矩阵乘法
struct JZ{
    vector<vl>a;
    int n,m;
    JZ(){}
    JZ(vector<vl>&a):a(a),n(a.size()){
        m=(a.size()?a[0].size():0);
    }
    JZ(int n,int m):n(n),m(m){
        a.resize(n,vl(m));
    }
    friend JZ operator*(const JZ& a,const JZ& b){
        vector<vl>c(a.n,vl(b.m));
        for(int i=0;i<a.n;i++){
            for(int j=0;j<b.m;j++){
                for(int k=0;k<a.m;k++){
                    c[i][j]+=a.a[i][k]*b.a[k][j];//
                }
            }
        }
        return c;
    }
};
暂无评论

发送评论 编辑评论


				
|´・ω・)ノ
ヾ(≧∇≦*)ゝ
(☆ω☆)
(╯‵□′)╯︵┴─┴
 ̄﹃ ̄
(/ω\)
∠( ᐛ 」∠)_
(๑•̀ㅁ•́ฅ)
→_→
୧(๑•̀⌄•́๑)૭
٩(ˊᗜˋ*)و
(ノ°ο°)ノ
(´இ皿இ`)
⌇●﹏●⌇
(ฅ´ω`ฅ)
(╯°A°)╯︵○○○
φ( ̄∇ ̄o)
ヾ(´・ ・`。)ノ"
( ง ᵒ̌皿ᵒ̌)ง⁼³₌₃
(ó﹏ò。)
Σ(っ °Д °;)っ
( ,,´・ω・)ノ"(´っω・`。)
╮(╯▽╰)╭
o(*////▽////*)q
>﹏<
( ๑´•ω•) "(ㆆᴗㆆ)
😂
😀
😅
😊
🙂
🙃
😌
😍
😘
😜
😝
😏
😒
🙄
😳
😡
😔
😫
😱
😭
💩
👻
🙌
🖕
👍
👫
👬
👭
🌚
🌝
🙈
💊
😶
🙏
🍦
🍉
😣
Source: github.com/k4yt3x/flowerhd
颜文字
Emoji
小恐龙
花!
上一篇
下一篇