模板总结2.0

0.目录

重新开一个模板总结。



1.图论


并查集(from LeetCode)

class UnionFind {
public:
	vector<int> parent;
	vector<int> size;
	int n;
	int setCount;
	
public:
	UnionFind(int _n): n(_n), setCount(_n), parent(_n), size(_n,1) {
		iota(parent.begin(),parent.end(),0);	//区间赋值 
	}
	
	int findset(int x) {
		return parent[x]==x ? x : parent[x]=findset(parent[x]);
	}
	
	bool unite(int x, int y) {
		x=findset(x);
		y=findset(y);
		if (x==y) {
			return false;
		}
		if (size[x]<size[y]) {
			swap(x,y);
		}
		parent[y]=x;
		size[x]+=size[y];
		--setCount;
		return true;
	}
	
	bool connected(int x,int  y) {
		x=findset(x);
		y=findset(y);
		return x==y;
	}
};

Tarjan 求桥边(vector邻接表存图) (from LeetCode)

class TarjanSCC {
private:
	const vector<vector<int>> &edges;
	const vector<vector<int>> &edgesId;
	vector<int> low;
	vector<int> dfn;
	vector<int> ans;
	int n;
	int ts;
	
private:
	void getCuttingEdge_(int u, int parentEdgeId) {
		low[u]=dfn[u]=++ts;
		for (int i=0; i<edges[u].size(); ++i) {
			int v=edges[u][i];
			int id=edgesId[u][i];
			if (dfn[v]==-1) {
				getCuttingEdge_(v,id);
				low[u]=min(low[u],low[v]);
				if (low[v]>dfn[u]) {
					ans.push_back(id);
				}
			}
			else if (id!=parentEdgeId) {
				low[u]=min(low[u],dfn[v]);
			}
		}
	}

public:
	TarjanSCC(int n_, const vector<vector<int>> &edges_, const vector<vector<int>> &edgesId_):\
		edges(edges_), edgesId(edgesId_), low(n_,-1), dfn(n_,-1), n(n_), ts(-1){}
	
	vector<int> getCuttingEdge() {
		for (int i=0; i<n; ++i) {
			if (dfn[i]==-1) {
				getCuttingEdge_(i,-1);
			}
		}
		return ans;
	}
};

网络流


template <typename Cap = int64_t>
class Dinic{
private:
	struct E{
		int to, rev;
		Cap cap;
	};
	int n, st, ed;
	vector<vector<E>> G;
	vector<int> lv, idx;
	vector<pair<int, int>> egs;
	bool BFS(){
		lv.assign(n, -1);
		queue<int> bfs;
		bfs.push(st); lv[st] = 0;
		while (not bfs.empty()){
			int u = bfs.front(); bfs.pop();
			for (auto e: G[u]) {
				if (e.cap <= 0 or lv[e.to]!=-1) continue;
				bfs.push(e.to); lv[e.to] = lv[u] + 1;
			}
		}
		return lv[ed] != -1;
	}
	Cap DFS(int u, Cap f){
		if (u == ed) return f;
		Cap ret = 0;
		for(int &i = idx[u]; i < int(G[u].size()); ++i) {
			auto &e = G[u][i];
			if (e.cap <= 0 or lv[e.to]!=lv[u]+1) continue;
			Cap nf = DFS(e.to, min(f, e.cap));
			ret += nf; e.cap -= nf; f -= nf;
			G[e.to][e.rev].cap += nf;
			if (f == 0) return ret;
		}
		if (ret == 0) lv[u] = -1;
		return ret;
	}
public:
	void init(int n_) { G.assign(n = n_, vector<E>()); egs.clear(); }
	void add_edge(int u, int v, Cap c){
		G[u].push_back({v, int(G[v].size()), c});
		G[v].push_back({u, int(G[u].size())-1, 0});
		egs.emplace_back(v, int(G[v].size()) - 1);
	}
	Cap max_flow(int st_, int ed_){
		st = st_, ed = ed_; Cap ret = 0;
		while (BFS()) {
			idx.assign(n, 0);
			Cap f = DFS(st, numeric_limits<Cap>::max());
			ret += f;
			if (f == 0) break;
		}
		return ret;
	}
	Cap flow_at(int eid) const {
		return G[egs[eid].first][egs[eid].second].cap;
	}
};


2.数学


质数线性筛

#define MaxN 2000005
long long mn[MaxN],P[MaxN];

void mk_tb(long long *p, long long n)	//打质数表,存到 p 数组,p[0] 为筛出的质数个数
{
	for (long long i=2; i<=n; ++i) {
		if (!mn[i]) p[mn[i]=++*p]=i;
		for (long long j=1; j<=mn[i] && i*p[j]<=n; ++j) mn[i*p[j]]=j;
	}
}

/*
前两百质数表
{2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31, 37, 41, 43, 47, 53, 59, 61, 
67, 71, 73, 79, 83, 89, 97, 101, 103, 107, 109, 113, 127, 131, 137, 
139, 149, 151, 157, 163, 167, 173, 179, 181, 191, 193, 197, 199, 211, 
223, 227, 229, 233, 239, 241, 251, 257, 263, 269, 271, 277, 281, 283, 
293, 307, 311, 313, 317, 331, 337, 347, 349, 353, 359, 367, 373, 379, 
383, 389, 397, 401, 409, 419, 421, 431, 433, 439, 443, 449, 457, 461, 
463, 467, 479, 487, 491, 499, 503, 509, 521, 523, 541, 547, 557, 563, 
569, 571, 577, 587, 593, 599, 601, 607, 613, 617, 619, 631, 641, 643, 
647, 653, 659, 661, 673, 677, 683, 691, 701, 709, 719, 727, 733, 739, 
743, 751, 757, 761, 769, 773, 787, 797, 809, 811, 821, 823, 827, 829, 
839, 853, 857, 859, 863, 877, 881, 883, 887, 907, 911, 919, 929, 937, 
941, 947, 953, 967, 971, 977, 983, 991, 997, 1009, 1013, 1019, 1021, 
1031, 1033, 1039, 1049, 1051, 1061, 1063, 1069, 1087, 1091, 1093, 
1097, 1103, 1109, 1117, 1123, 1129, 1151, 1153, 1163, 1171, 1181, 
1187, 1193, 1201, 1213, 1217, 1223}
*/

n的阶乘中质数 p 的次数

// n! 中 p 的次数 
long long get_cntP(long long n, long long p)
{
	long long ret=0;
	while (n>1)
		ret+= n/=p;
	return ret; 
}

遍历约数

#include <cstdio>


void test()
{
	int t,k=1,cnt=0;
	scanf("%d",&t);
	while (k<t) {
		if (t%k==0) printf("[%3d] %d\n",++cnt,k);
		k=t/(t/(k+1));
	}
	puts(".");
}

void solve(int n)
{
	int L=1,R=n;
	while (L<R) {
		if (n%L==0) printf("%d\n",L);
		if (n%R==0) printf("%d\n",R);
		
		R=n/(L+1);
		L=n/R;
	}
	if (L==R && n%L==0) printf("%d\n",L);
	
	puts("*\n");
}

/*
一百万以内约数个数前十的
{{240, 720720}, {240, 942480}, {240, 831600}, {240, 997920}, {240, 
  982800}, {224, 786240}, {224, 665280}, {224, 960960}, {216, 
  776160}, {216, 887040}}
*/

FWT(2021牛客6 D 的某个队提交的)

#include <bits/stdc++.h>
#define fp(i,a,b) for(int i=(a),_##i=(b)+1;i<_##i;++i)
#define fd(i,a,b) for(int i=(a),_##i=(b)-1;i>_##i;--i)
#define file(s) freopen(s".in","r",stdin)//,freopen(s".out","w",stdout)
template<class T>void In(T&x){
    char c;T y=1;
    while(c=getchar(),!isdigit(c)&&c!=-1){if(c=='-')y=-1;}x=c-'0';
    while(c=getchar(),isdigit(c)){x=10*x+c-'0';}x*=y;
}
template<class T,class ...T_>void In(T&x,T_&...y){In(x),In(y...);}
using namespace std;
constexpr int N = 2e5 + 5, P = 1e9 + 7;
using db = double;
using arr = int[N];
using ll = long long;
/*---------------------------------------------------------------------------*/
#define ADD(a, b) ((a) += (b), (a) >= P ? (a) -=P : 0) // (a += b) %= P
#define SUB(a, b) ((a) -= (b), (a) < 0 ? (a) += P: 0)  // ((a -= b) += P) %= P
//#define ADDE(a, b, c) ((a) = (b), ADD(a, c))         // a = (b + c) % P
//#define SUBE(a, b, c) ((a) = (b), SUB(a, c))         // a = (b - c + P) % P
#define INV(a) (POW(a, P - 2))
int POW(ll a,int b){ll x=1;for(;b>=1;b>>=1,a=a*a%P)if(b&1)x=x*a%P;return x;}
namespace FWT{
    const ll I2 = (P + 1) >> 1;
    int L;
    void calc1(int &x, int &y) { int z = y; y = x, ADD(x, z), SUB(y, z); }
    void calc2(int &x, int &y) { int z = y * I2 %P; x = x * I2 % P, y = x, ADD(x, z), SUB(y, z); }
    void Init(int n) { for (L = 1; L < n; L <<= 1); }
    void XOR(vector<int> &a, const int x) {
        a.resize(L);
        for (int o = 2, k = 1; o <= L; k = o, o <<= 1)
            for (int i = 0; i < L; i += o)
                fp(j, i, i + k - 1) x ? calc1(a[j], a[j + k]) : calc2(a[j], a[j + k]);
    }
}
class Poly{
    vector<int> a;
    static Poly workFWT(void(*op)(vector<int>&,int),Poly&A,Poly&B){
        FWT::Init(max(A.deg(),B.deg()));
        op(A.a,1),op(B.a,1);
        fp(i,0,FWT::L-1)A[i]=(ll)A[i]*B[i]%P;
        return op(A.a,0),A;
    }
public:
    Poly(const vector<int>&t){a=t;}
    Poly(int n=0){a.assign(n+1,0);}
    int deg(){return(int)a.size()-1;}
    int&operator[](const int&x){return a[x];}
    template<class T>void copy(T b,int L,int x){std::copy(b,b+L,a.begin()+x);}
    void Print(){fp(i,0,deg())printf("%d%c",a[i]," \n"[i==deg()]);}
    friend Poly operator^(Poly A,Poly B){return workFWT(FWT::XOR,A,B);}
};
int n;arr p,sp,f,g;
void cdq(int L,int R,int Len){
    if(L==R)return L==n-1?0:(f[L]=(ll)(f[L]+1)*INV(g[L])%P),void();
    int m=(L+R)>>1,hL=Len>>1;
    Poly a(hL),b(hL);
    cdq(m+1,R,hL);
    b.copy(p+hL,hL,0),a.copy(f+L+hL,hL,0),a=a^b;
    fp(i,0,hL-1)f[L+i]=(f[L+i]+a[i])%P;
    cdq(L,m,hL);
}
void Solve(){
    fp(i,0,n-1)In(p[i]),sp[i]=sp[i-1]+p[i],g[i]=f[i]=0;
    int m=log2(n),isp=INV(sp[n-1]);
    fp(i,0,n-1)p[i]=(ll)p[i]*isp%P,sp[i]=(ll)sp[i]*isp%P;
    fp(i,0,n-1)fp(j,0,m-1)if(!(i>>j&1))
        ADD(g[i],sp[(1<<(j+1))-1]),SUB(g[i],sp[(1<<j)-1]);
    cdq(0,n-1,n);
    printf("%d\n",f[0]);
}
int main(){
#ifdef LOCAL
    file("s");
#endif
    In(n);
    while(In(n),n!=-49)
        Solve();
    return 0;
}

exgcd

long long exgcd(long long aa,long long bb,long long &x,long long &y)//扩展欧几里得算法
{
    if(bb==0)
    {
        x=1;y=0;
        return aa;  //到达递归边界开始向上一层返回
    }
    long long r=exgcd(bb,aa%bb,x,y);
    long long temp=y;    //把x y变成上一层的
    y=x-(aa/bb)*y;
    x=temp;
    return r;     //得到a b的最大公因数
}

组合数(含阶乘)

#define Ha 998244353
typedef long long LL;
LL jc[100005];

LL ksm(LL x, LL t)	//快速幂 x^t
{
	LL ret=1;
	for (; t; (t>>=1),(x=x*x%Ha)) if (t&1) ret=ret*x%Ha;
	return ret;
}

LL C(LL x, LL y)	//组合数 x 选 y
{
	if (y>x || y<0) return 0;
	
	LL ret=jc[x];
	ret=ret*ksm(jc[y],Ha-2)%Ha;
	ret=ret*ksm(jc[x-y],Ha-2)%Ha;
	return ret;
}

int main() {
	//预处理阶乘
	jc[0]=jc[1]=1;
	for (int i=2; i<=100000; i++) {
		jc[i]=(jc[i-1]*i)%Ha;
	}
	return 0;
}

高精度模板(来自 https://www.luogu.com.cn/blog/xuanxue/solution-p1303

#include<iostream>
#include<cstring>
#include<cstdlib>
#include<cstdio>
#define LL long long
using namespace std;
int m;
const long long mod=40961,G=3,Ginv=(mod+1)/3;
int r[240100];
LL ksm(LL a,LL b,LL mod)
{
    LL ans=1;
    for(;b;b>>=1,a=a*a%mod)
        if(b&1)ans=ans*a%mod;
    return ans;
}
void NTT(int limit,LL *l,int opt)
{
    for(int i=0;i<limit;++i)
    if(i<r[i])swap(l[i],l[r[i]]);
    for(int mid=1;mid<limit;mid<<=1)
    {
        LL wn,len=mid<<1;;
        if(opt==1)wn=ksm(G,(mod-1)/len,mod);
        else wn=ksm(Ginv,(mod-1)/len,mod);
        for(int j=0;j<limit;j+=len)
        {
            LL w=1;
            for(int k=j;k<mid+j;++k,(w*=wn)%=mod)
            {
                int x=l[k],y=w*l[k+mid]%mod;
                l[k]=(x+y)%mod;
                l[k+mid]=(x-y+mod)%mod;
            }
        }
    }
    if(opt==-1)
    {
        LL inv=ksm(limit,mod-2,mod);
        for(int i=0;i<=limit;i++) l[i]=l[i]*inv%mod;
    }
}
/*------以下为重载部分------*/ 
struct gj
{
    int len,zheng;//len:长度 zheng:正负标记0为负1为正 
    LL v[5000];
    gj(){len=0;memset(v,0,sizeof(v));zheng=1;}
    gj(int x)
    {
        if(x>=0)zheng=1;
        else x=-x,zheng=0;
        len=0;memset(v,0,sizeof(v));
        while(x)
        {
            v[++len]=x%10;
            x/=10;
        }
    }
    friend bool operator <(const gj &a,const gj &b)
    {
        if(a.len<b.len)return 1;
        if(a.len>b.len)return 0;
        for(int i=a.len;i>=1;--i)
        {
            if(a.v[i]<b.v[i])return 1;
            if(a.v[i]>b.v[i])return 0;
        }
        return 0;
    }
}n,a,b;
ostream& operator << (ostream &out,const gj &a);
istream& operator >> (istream &in,gj &a);
gj operator -(gj a,gj b);
gj operator +(gj a,gj b);
gj operator *(gj a,gj b);

gj operator +(gj a,gj b)
{
    if(!a.zheng&&!b.zheng)
    {
        a.zheng=b.zheng=1;
        gj c=a+b;
        c.zheng=0;
        return c;
    }
    if(!a.zheng&&b.zheng)
    {
        a.zheng=b.zheng=1;
        return b-a;
    }
    if(a.zheng&&!b.zheng)
    {
        a.zheng=b.zheng=1;
        return a-b;
    }
    int len=a.len+b.len;
    gj c;
    c.len=len;
    for(int i=1;i<=len;++i)c.v[i]=a.v[i]+b.v[i];
    for(int i=1;i<=len;++i)
    {
        if(c.v[i]>=10)
        {
            ++c.v[i+1];
            c.v[i]-=10;
        }
    }
    while(c.len&&!c.v[c.len])c.len--;
    return c;
}
gj operator -(gj a,gj b)
{
    if(!a.zheng&&!b.zheng)
    {
        a.zheng=b.zheng=1;
        return b-a;
    }
    if(!a.zheng&&b.zheng)
    {
        a.zheng=1;
        gj c=a+b;
        c.zheng=0;
        return c;
    }
    if(a.zheng&&!b.zheng)
    {
        b.zheng=1;
        gj c=a+b;
        return c;
    }
    if(a.zheng&&b.zheng&&a<b)
    {
        gj c=b-a;
        c.zheng=0;
        return c;
    }
    int len=max(a.len,b.len);
    gj c;
    for(int i=1;i<=len;++i)c.v[i]=a.v[i]-b.v[i];
    c.len=len;
    for(int i=1;i<=c.len;++i)
    {
        if(c.v[i]<0)
        {
            c.v[i+1]--;
            c.v[i]+=10;
        }
    }
    while(c.len&&!c.v[c.len])c.len--;
    return c;
}
gj operator *(gj a,gj b)
{
    int limit=1,tot,l=0;
    gj c;
    a.len--;b.len--;
    for(int i=0;i<=a.len;++i)a.v[i]=a.v[i+1];a.v[a.len+1]=0;
    for(int i=0;i<=b.len;++i)b.v[i]=b.v[i+1];b.v[b.len+1]=0;
    while(limit<=a.len+b.len)limit<<=1,l++;
    for(int i=0;i<=limit;i++) r[i]=(r[i>>1]>>1) | ((i&1)<<(l-1) );
    NTT(limit,a.v,1);NTT(limit,b.v,1);
    for(int i=0;i<=limit;i++) a.v[i]=a.v[i]*b.v[i]%mod;
    NTT(limit,a.v,-1);
    for(int i=0;i<=limit;i++) c.v[i]=a.v[i];
    for(int i=0;i<=limit;i++)
    {
        if(c.v[i]>=10)
        {
            c.v[i+1]+=c.v[i]/10,c.v[i]%=10;
            if(i+1>limit) limit++;
        }
    }
    for(int i=limit;i>=0;i--)if(c.v[i]==0) limit--;else break;
    c.len=limit+1;
    for(int i=c.len;i>=1;--i)c.v[i]=c.v[i-1];c.v[0]=0;
    for(int i=1;i<=c.len;++i)swap(c.v[i],c.v[c.len-i+1]);
    if(a.zheng!=b.zheng)c.zheng=0;
    else c.zheng=1;
    return c;
}
gj operator /(gj a,long long b)
{
    gj c;int d=0;
    for(int i=a.len;i>=1;--i)
    c.v[++c.len]=((d*10+a.v[i])/b),d=(d*10+a.v[i])%b;
    for(int i=1;i<=c.len/2;++i)swap(c.v[i],c.v[c.len-i+1]);
    if(!a.len||!b||(a.zheng&&b>0)||(!a.zheng&&b<0))c.zheng=1;
    else c.zheng=0;
    while(c.v[c.len]==0&&c.len>1)--c.len;
    return c;
}
istream& operator >> (istream &in,gj &a)//方便使用cin
{
    char lin[5010];int len;
    scanf("%s",lin+1);
    len=a.len=strlen(lin+1);
    if(lin[1]=='-')a.zheng=0,a.len--;
    else a.zheng=1;
    for(int i=1;i<=a.len;++i)a.v[i]=lin[len-i+1]-'0';
    return in;
}
ostream& operator << (ostream &out,const gj &a)//方便使用cout 
{
    if(!a.len)//一定要注意答案是0得情况 
    {
        cout<<"0";
        return out;
    }
    if(!a.zheng)cout<<"-";
    for(int i=a.len;i>=1;i--)printf("%d",a.v[i]);
    return out;
}
/*------以上为重载部分------*/ 
int main()
{
    cin>>a>>b;
    cout<<a*b;
    return 0;
}

文件目录遍历

void testAllFiles(string path)
{
    long hFile = 0; //文件信息
    struct _finddata_t fileinfo;    //存储文件信息的结构体
    string p;

    if ((hFile = _findfirst(p.assign(path).append("/*").c_str(), &fileinfo)) != -1) {  //第一次查找

        do {

            if ((fileinfo.attrib & _A_SUBDIR)) {    //若找到的是文件夹

                if (strcmp(fileinfo.name, ".") != 0 && strcmp(fileinfo.name, "..") != 0) {

                    testAllFiles(p.assign(path).append("/").append(fileinfo.name));      //递归进入文件夹

                }

            }
            else {  //若找到的不是文件夹


            }

        } while (_findnext(hFile, &fileinfo) == 0);

    }

    _findclose(hFile);  //结束查找
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值