一些模板的整理

塔幂(欧拉函数降幂)

2019 icpc 南京网络赛 super_log
题目链接:https://nanti.jisuanke.com/t/41299

#include
#define rep(i,j,k) for(int i=j;i<=k;i++)
#define LL long long
using namespace std;
LL Mod(LL x,LL mod)
{
	return x>=1;
    }
    return res;
}
LL phi(LL n)
{
	LL up=sqrt(n),res=n;
	rep(i,2,up) if(n%i==0)
	{
		res=res/i*(i-1);
		while(n%i==0) n/=i;
	}
	if(n>1) res=res/n*(n-1);
	return res;
}
LL calc(LL a,LL b,LL p)
{
	if(b==0) return Mod(1,p);
	if(p==1) return Mod(a,p);
	return Pow(a,calc(a,b-1,phi(p)),p);
}
int main()
{
	LL a,b,c,p,T;
    scanf("%lld",&T);
    while(T--)
    {
        scanf("%lld%lld%lld",&a,&b,&p);
        printf("%lld\n",calc(a,b,p)%p);
    }
    return 0;
}

李超线段树(洛谷 P4254 [JSOI2008]Blue Mary开公司)

题目链接:https://www.luogu.org/problem/P4254

//洛谷 P4254 
#include
#define rep(i,j,k) for(int i=j;i<=k;i++)
using namespace std;
const int mxn=100005;
int n,m,T,cnt;
double k[mxn],b[mxn];
struct Seg
{
	int l,r,pos;
}t[mxn<<2];
double Get(int i,int x)  //第i条线段
{
	return k[i]*(x-1)+b[i];
}
void Modify(int now,int l,int r,int x)
{
	t[now].l=l,t[now].r=r;
	if(l==r)
	{
		if(Get(x,l)>Get(t[now].pos,l))
			t[now].pos=x;
		return;
	}
	int mid=l+r>>1;
	if(k[x]>k[t[now].pos])  //新线段斜率大 
	{
		if(Get(x,mid)>Get(t[now].pos,mid))
		{
			Modify(now<<1,l,mid,t[now].pos);
			t[now].pos=x;
		}
		else Modify(now<<1|1,mid+1,r,x);
	}
	else
	{
		if(Get(x,mid)>Get(t[now].pos,mid))
		{
			Modify(now<<1|1,mid+1,r,t[now].pos);
			t[now].pos=x;
		}
		else Modify(now<<1,l,mid,x);
	}
}
double Query(int now,int x)
{
	int l=t[now].l,r=t[now].r;
	if(l==r) return Get(t[now].pos,x);
	int mid=l+r>>1;
	if(x<=mid) return max(Get(t[now].pos,x),Query(now<<1,x));
	return max(Get(t[now].pos,x),Query(now<<1|1,x));
}
int main()
{
	scanf("%d",&n);
	while(n--)
	{
		char opt[5];
		scanf("%s",opt);
		if(opt[0]=='P')
		{
			cnt++;
			scanf("%lf%lf",&b[cnt],&k[cnt]);
			Modify(1,1,100000,cnt);
		}
		else
		{
			int x;
			scanf("%d",&x);
			printf("%d\n",(int)Query(1,x)/100);
		}
	}
	return 0;
}

杜教筛(mu & phi 前缀和)

#include
#define N 5000000
#define LL long long
#define rep(i,j,k) for(int i=j;i<=k;i++)
using namespace std;
const int mxn=5000005;
int n,m,T;
map  P;  //mu,phi
map  M;
int pri[mxn];
bool vis[mxn];
LL mu[mxn],phi[mxn];
void init()
{
	mu[1]=phi[1]=1;
	rep(i,2,N)
	{
		if(!vis[i]) pri[++pri[0]]=i,mu[i]=-1,phi[i]=i-1;
		rep(j,1,pri[0])
		{
			if((LL)i*pri[j]>N) break;
			vis[i*pri[j]]=1;
			if(i%pri[j]==0)
			{
				mu[i*pri[j]]=0;
				phi[i*pri[j]]=phi[i]*pri[j];
				break;
			}
			mu[i*pri[j]]=-mu[i];
			phi[i*pri[j]]=phi[i]*(pri[j]-1);
		}
	}
	rep(i,1,N) mu[i]+=mu[i-1],phi[i]+=phi[i-1];
}
LL S_phi(LL n)
{
	if(n<=N) return phi[n];
	if(P.count(n)) return P[n];
	LL res=n*(n+1)/2;
	for(LL i=2,last=0;i<=n;i=last+1)
	{
		last=n/(n/i);
		res-=(last-i+1)*S_phi(n/i); 
	}
	P[n]=res;
	return res;
}
int S_mu(int n)
{
	if(n<=N) return mu[n];
	if(M.count(n)) return M[n];
	int res=1;
	for(LL i=2,last=0;i<=n;i=last+1)
	{
		last=n/(n/i);
		res-=(int)(last-i+1)*S_mu(n/i); 
	}
	M[n]=res;
	return res;
}
int main()
{
	init();
	scanf("%d",&T);
	while(T--)
	{
		scanf("%d",&n);
		printf("%lld %d\n",S_phi(n),S_mu(n));
	}
	return 0;
}

模拟退火讲解:https://www.luogu.org/blog/m-sea/qian-tan-SA

二分图匹配-匈牙利算法

题目链接:https://nanti.jisuanke.com/t/A1542

#include
#define LL long long
#define rep(i,j,k) for(int i=j;i<=k;i++)
using namespace std;
const int mxn=105;
int n,m,T,cnt;
int link[mxn];
bool vis[mxn];
bool dp[mxn][mxn];
bool dfs(int a)
{
	rep(i,1,n) if(dp[a][i] && !vis[i])
	{
		vis[i]=1;
		if(!link[i] || dfs(link[i]))
		{
			link[i]=a;
			return 1;
		}
	}
	return 0;
}
int main()
{
	scanf("%d",&T);
	while(T--)
	{
		int ans=0;
		scanf("%d%d",&n,&m);
		memset(link,0,sizeof link);
		memset(dp,0,sizeof dp);
		rep(i,1,m)
		{
			int u,v;
			scanf("%d%d",&u,&v);
			dp[u][v]=1;
		}
		rep(k,1,n) rep(i,1,n) rep(j,1,n)
			dp[i][j]=dp[i][j]|(dp[i][k]&dp[k][j]);
		rep(i,1,n)
		{
			memset(vis,0,sizeof vis);
			if(dfs(i)) ans++;
		}
		printf("%d\n",n-ans);
	}
	return 0;
}

你可能感兴趣的:(模板)