【T】03

A 【模板】快速幂

板子,略

cpp 复制代码
#include<bits/stdc++.h>
#define ll long long
using namespace std;
ll a,p,k;
int main()
{
	scanf("%lld%lld%lld",&a,&p,&k);
	printf("%lld^%lld mod %lld=",a,p,k);
	ll ans=1,w=a;a%=k;
	while(p)
	{
		if(p&1)
		{
			ans=ans*w%k;
		}
		w=w*w%k;
		p>>=1;
	}printf("%lld",ans%k);
}

B【模板】矩阵快速幂

cpp 复制代码
#include<bits/stdc++.h>
using namespace std;
long long mod=1000000007;
long long n,k;
struct sq{
	long long num[102][102];
	sq(){memset(num,0,sizeof(num));}//初始化num数组为空
};
sq operator *(const sq &a,const sq &b)
{
	sq ans;
	for(int k=1;k<=n;k++)
	for(int i=1;i<=n;i++)
	{
		for(int j=1;j<=n;j++)
		{
			ans.num[i][j]=(ans.num[i][j]+a.num[i][k]*b.num[k][j]%mod)%mod;
		}
	}return ans;
}//一个重载
sq x,y,ans;
long long read()
{
	char s;long long ans=0;
	s=getchar();
	while(s>'9'||s<'0'){s=getchar();}
	while(s>='0'&&s<='9')
	{
		ans=ans*10+s-'0';
		s=getchar();
	}
	return ans;
}//只是个快速读入函数
inline void init()
{
	n=read();k=read();//用scanf,cin也行
	for(int i=1;i<=n;i++)
		for(int j=1;j<=n;j++)
			x.num[i][j]=read();
	for(int i=1;i<=n;i++)
	{
			y.num[i][i]=1;
			ans.num[i][i]=1;
	}
}
int main(){
	init();
	while(k)
	{
		if(k&1){ans=ans*x;}
		x=x*x;
		k>>=1;
	}
	for(int i=1;i<=n;i++)
	{
		for(int j=1;j<=n;j++)
			printf("%lld ",ans.num[i][j]);
		printf("\n");
	}
	   return 0;
}

C【模板】有理数取余

除以一个数等于乘以它的逆元,逆元可以用费马小定理求

cpp 复制代码
#include<bits/stdc++.h>
#define ll long long 
using namespace std;
ll a,b,mod=19260817;
inline ll read()
{
	ll ans=0;char s=getchar();
	while(s>'9'||s<'0')s=getchar();
	while(s>='0'&&s<='9')
	{
		ans=((ans<<1)%mod+(ans<<3)%mod+(s&15))%mod;
		s=getchar();
	}return ans;
}
ll quick_m(ll i,ll n)
{
	i%=mod;
	ll ans=1,ds=i;
	while(n)
	{
		if(n&1)
		{
			ans=ans*ds%mod;
		}
		ds=ds*ds%mod;
		n>>=1;
	}return ans%mod;
}
signed main(){
	a=read();b=read();
	if(b==0){printf("Angry!");return 0;}
	printf("%lld",a*quick_m(b,mod-2)%mod);
	return 0;
}

D 质因数分解

cpp 复制代码
#include<bits/stdc++.h>
int a;
int main()
{
	scanf("%d",&a);
	for(int i=2;i*i<=a;i++)
	{
		if(a%i==0)
		{
			printf("%d",std::max(a/i,i));
			return 0;//找到一个因数就可以停了,另一个因数就是最大的那个
		}
	}
}

E 质数筛

数据不大的话,每个数都直接用质数判断法也能过

cpp 复制代码
#include<bits/stdc++.h>
using namespace std;
int n,a;
int main()
{
    scanf("%d",&n);
    for(int i=1;i<=n;i++)
    {
        scanf("%d",&a);
        bool f=1;
        for(int j=2;j*j<=a;j++)
        {
            if(a%j==0){f=0;break;}
        }
        if(f==1&&a!=1)printf("%d ",a);//是质数
    }
}

F 【模板】线性筛素数

这里用的欧拉筛

cpp 复制代码
#include<bits/stdc++.h>
using namespace std;
bool ans[100000002];
int z[6000005],p;
int n,m,a;
int main()
{
	scanf("%d%d",&n,&m);
	for(int i=2;i<=n;i++)
	{
		if(!ans[i])z[++p]=i;//printf("[%d]",z[p]);
		for(int j=1;j<=p&&z[j]*i<=n;j++)
		{
			ans[i*z[j]]=1;
			if(i%z[j]==0)break;
		}
	}
	for(int i=1;i<=m;i++)
	{
		scanf("%d",&a);
		printf("%d\n",z[a]);
	}
	return 0;
} 

G 晨跑

求三个数的最小公倍数

cpp 复制代码
#include<bits/stdc++.h>
#define ll long long
using namespace std;
ll gcd(ll x,ll y){return !y?x:gcd(y,x%y);}
ll lcm(ll x,ll y){return x*y/gcd(x,y);}
int main()
{
    ll a,b,c;
    scanf("%lld%lld%lld",&a,&b,&c);
    printf("%lld",lcm(a,lcm(b,c)));
}

H 最大公约数和最小公倍数问题
x ∗ y = g c d ( x , y ) ∗ l c m ( x , y ) x*y=gcd(x,y)*lcm(x,y) x∗y=gcd(x,y)∗lcm(x,y)

枚举x然后判断算出对应y是否满足gcd,lcm就行,可能要特判

cpp 复制代码
#include<bits/stdc++.h>
#define ll long long
using namespace std;
ll gcd(ll x,ll y){return !y?x:gcd(y,x%y);}
ll lcm(ll x,ll y){return x*y/gcd(x,y);}
int main()
{
    ll a,b,ans=0;
    scanf("%lld%lld",&a,&b);
    if(a==b)ans--;//这样会存在x,y相同的一组,下面枚举时会多算一组,故删去
    for(ll i=1;i*i<=a*b;i++)
        if(a*b%i==0&&gcd(i,a*b/i)==a)ans+=2;
    printf("%lld",ans);
}

I 【模板】模意义下的乘法逆元

建议看我之前博客线性递推式部分
a − 1 = − ⌊ p / a ⌋ ∗ ( p m o d a ) − 1 ( m o d p ) a^{-1}=-⌊p/a⌋*(p \ mod \ a )^{-1} \ \ \ \ (mod \ p) a−1=−⌊p/a⌋∗(p mod a)−1 (mod p)

cpp 复制代码
#include<bits/stdc++.h>
#define ll long long 
using namespace std;
int n,p,inv[3000005];
signed main(){
	scanf("%d%d",&n,&p);
	inv[0]=1;inv[1]=1;
	printf("1\n");
	for(int i=2;i<=n;i++)
	{
		inv[i]=(ll)inv[p%i]*(p-p/i)%p;//-p/i不能直接取模,要+p变成正数再%p
		printf("%d\n",inv[i]);
	}
	return 0;
}
/*下面是欧拉筛版
#include <bits/stdc++.h>
#define ll long long
using namespace std;
const int N=3000005;
ll n,p;
bool vis[N];
ll z[N];
ll inv[N];
ll quick(ll a,ll k,ll mod)
{
	ll ans=1,as=a;
	while(k)
	{
		if(k&1)
		{
			ans=ans*as%mod;
		}
		as=as*as%mod;
		k>>=1;
	}
	return ans;
}
int main()
{
    scanf("%lld%lld",&n,&p);
    vis[1]=1,inv[1]=1;
    for (int i=2;i<=n;i++)
    {
        //printf("(%d\n",i);
        if (!vis[i])z[++z[0]]=i,inv[i]=quick(i,p-2,p);
        for (int j=1;j<=z[0]&&i*z[j]<=n;j++)
        {
            vis[i*z[j]]=1;
            inv[i*z[j]]=(inv[i]*inv[z[j]])%p;
            if (i%z[j]==0) break;
        }
    }
    for (int i=1;i<=n;i++)
    printf("%lld\n",inv[i]);
    return 0;
}*/

J 沙拉公主的困惑

求 1 − > N ! 1->N! 1−>N!中与 M ! M! M!互质的个数

推演一下,最后得 N ! M ! ϕ ( M ! ) \frac {N!}{M!} \phi{(M!)} M!N!ϕ(M!)

=> N ! ( 1 − p 1 p 1 ) ( 1 − p 2 p 2 ) . . . ( 1 − p k p k ) N!(\frac {1-p_1}{p_1})(\frac {1-p_2}{p_2})...(\frac {1-p_k}{p_k}) N!(p11−p1)(p21−p2)...(pk1−pk)

一堆预处理,质数+线性求逆+阶乘。。。

cpp 复制代码
#include<bits/stdc++.h>
#define ll long long 
using namespace std;
inline ll read()
{
	ll ans=0;char s=getchar();
	while(!isdigit(s))s=getchar();
	while(isdigit(s))
	{
		ans=(ans*10)+(s&15);
		s=getchar();
	}return ans;
}
const int N=1e7+10;
int T;
ll n,m,mod;
int z[N],p;
bool vis[N];
void get_prime()
{
	for(int i=2;i<N;i++)
	{
		if(!vis[i])z[++p]=i;
		for(int j=1;j<=p&&i*z[j]<N;j++)
		{
			vis[i*z[j]]=1;
			if(i%z[j]==0)break;
		}
	}
}
ll inv[N],mul[N],pt[N];
int main()
{
	scanf("%d%lld",&T,&mod);
	get_prime();
	inv[1]=1;inv[0]=1;
	for(int i=2;i<N;i++)
		inv[i]=inv[mod%i]*(mod-mod/i)%mod;
	mul[1]=1;
	for(int i=2;i<N;i++)
		mul[i]=mul[i-1]*i%mod;
	pt[1]=1;
	for(int i=2;i<N;i++)
		if(!vis[i])
			 pt[i]=pt[i-1]*(i-1)%mod*inv[i%mod]%mod;
		else pt[i]=pt[i-1];
	while(T--)
	{
		n=read();m=read();
		printf("%lld\n",mul[n]*pt[m]%mod);
	}
}//开个o2就过了

K 同余方程

扩欧板子题

cpp 复制代码
#include<bits/stdc++.h>
using namespace std;
void gcd(int a,int b,int &x,int &y)
{
	if(!b)
	{
		x=1;y=0;
		return ;
	}
	gcd(b,a%b,x,y);
	int xx=y,yy=x-a/b*y;
	x=xx;y=yy;
	return ;
}
int a,b,x,y;
int main()
{
	scanf("%d%d",&a,&b);
	gcd(a,b,x,y);
	printf("%d",(x+b)%b);
}
相关推荐
Ysjt | 深2 小时前
C++多线程编程入门教程(优质版)
java·开发语言·jvm·c++
ephemerals__2 小时前
【c++丨STL】list模拟实现(附源码)
开发语言·c++·list
Microsoft Word2 小时前
c++基础语法
开发语言·c++·算法
一只小小汤圆3 小时前
opencascade源码学习之BRepOffsetAPI包 -BRepOffsetAPI_DraftAngle
c++·学习·opencascade
legend_jz3 小时前
【Linux】线程控制
linux·服务器·开发语言·c++·笔记·学习·学习方法
嘿BRE3 小时前
【C++】几个基本容器的模拟实现(string,vector,list,stack,queue,priority_queue)
c++
ö Constancy4 小时前
c++ 笔记
开发语言·c++
fengbizhe4 小时前
笔试-笔记2
c++·笔记
徐霞客3204 小时前
Qt入门1——认识Qt的几个常用头文件和常用函数
开发语言·c++·笔记·qt