#include <cstdio>
#include <cstring>
#include <algorithm>
#include <iostream>
#include <cmath>
#include <queue>
#include <vector>
#include <set>
#include <map>
#define int long long
const int maxn=1e4+10;
int mul_mod(int a,int b,int n){
return a*b%n;
}
//快速幂取模
int pow_mod(int a,int n,int mod){
if(n==0)return 1;
int ans=pow_mod(a,n/2,mod);
ans=ans*ans%mod;
if(n%2==1)ans=ans*a%mod;
return ans;
}
int gcd(int a,int b){
return b==0?a:gcd(b,a%b);
}
//扩展GCD
int ex_gcd(int a,int b,int &x,int &y){
if(b==0){x = 1;y = 0;return a;}
int g = ex_gcd(b,a%b,x,y);
int temp = x;
x = y;
y = temp - a/b*y;
return g;
}
//扩展欧几里得的另一种写法
void ex_gcd(int a,int b,int &d,int &x,int &y){
//求解ax+by=gcd(a,b)的一组解
if(!b){
d=a,x=1,y=0;
}
else{
ex_gcd(b,a%b,d,y,x);
y-=x*(a/b);
}
}
//逆元
int inv(int a,int mod){
int X,Y;
int g = ex_gcd(a,mod,X,Y);
if(g!=1)return -1;
return (X%mod + mod)%mod;
}
//费马小定理求逆元(质数)
ll poww(ll a,ll b)
{
b-=2;//费马小定理要减2
ll res=1;
while(b)
{
if(b&1) res=(res*a)%mod;
a=(a*a)%mod;
b>>=1;
}
return res;
}
//a^x=b(mod n),求解x,大步小步算法
int log_mod(int a,int b,int n){
int m,v,e=1;
m=(int)sqrt(n+0.5);
v=inv(pow_mod(a,m,n),n);
map<int,int>x;
x[1]=0;
for(int i=1;i<m;i++){
e=mul_mod(e,a,n);
if(!x.count(e))x[e]=i;
}
for(int i=0;i<m;i++){
if(x.count(b))return i*m+x[b];
b=mul_mod(b,v,n);
}
return -1;
}
//中国剩余定理
int china(int n,int *a,int *m){
int M=1,d,y,x=0;//M为每个m[i]的乘积
for(int i=1;i<=n;i++){
M*=m[i];
}
for(int i=1;i<=n;i++){
int w=M/m[i];//求每个wi,还需要求每个wi的逆
ex_gcd(m[i],w,d,d,y);//因为m[i]与w互素,则求解的是m[i]*d+w*y=1,对m[i]取模后有w*y=1,即y为w的数论倒数
x=(x+y*w*a[i])%M;
}
return (x+M)%M;
}
//可以处理不互素的中国剩余定理
int ex_china(int n,int *C,int *M){
for(int i = 2;i<=n;i++){
int M1 = M[i-1],M2 = M[i],C1 = C[i-1],C2 = C[i];
int g = gcd(M1,M2);
if((C2-C1)%g)return -1;
M[i] = M1/g*M2;
int INV = inv(M1/g,M2/g);
if(INV==-1)return -1;
C[i] = C1 + (INV*((C2-C1)/g))%(M2/g)*M1;
C[i] = (C[i]%M[i] + M[i])%M[i];
}
return C[n];
}
再来个矩阵和矩阵快速幂的模板
typedef long long lint
struct matrix
{
lint m[10][10];
matrix()
{
memset(m,0,sizeof(m));//注意要清零
}
};
matrix operator * (const matrix & a,const matrix & b)
{
matrix c;
for (int i=1; i<=9; i++)
for (int j=1; j<=9; j++)
{
c.m[i][j]=0;
for (int k=1; k<=9; k++)
c.m[i][j]=(c.m[i][j]+a.m[i][k]*b.m[k][j])%mod;//一般题目都要求要modulo一个数
}
return c;
}
matrix quick(matrix base,int pow)
{
matrix a;
for (int i=1; i<=9; i++) a.m[i][i]=1;//单位阵,矩阵乘法时要用到
while (pow)
{
if (pow&1) a=a*base;
base=base*base;
pow>>=1;
}
//if (pow==0) return base;
return a;
}
BM模板,用于求解线性递推,注意往vector里面装数至少要是8个,越多越好
模板题:牛客多校第二场B
#include <cstdio>
#include <cstring>
#include <cmath>
#include <algorithm>
#include <vector>
#include <string>
#include <map>
#include <set>
#include <cassert>
#include<bits/stdc++.h>
using namespace std;
#define rep(i,a,n) for (int i=a;i<n;i++)
#define per(i,a,n) for (int i=n-1;i>=a;i--)
#define pb push_back
#define mp make_pair
#define all(x) (x).begin(),(x).end()
#define fi first
#define se second
#define SZ(x) ((int)(x).size())
#define int long long
typedef vector<int> VI;
typedef long long ll;
typedef pair<int,int> PII;
const ll mod=1000000007;
const int maxn=1028;
ll powmod(ll a,ll b,ll mod) {ll res=1;a%=mod; assert(b>=0); for(;b;b>>=1){if(b&1)res=res*a%mod;a=a*a%mod;}return res;}
// head
ll n,k;
namespace linear_seq {
const int N=1030;
ll res[N],base[N],_c[N],_md[N];
vector<int> Md;
void mul(ll *a,ll *b,int k) {
rep(i,0,k+k) _c[i]=0;
rep(i,0,k) if (a[i]) rep(j,0,k) _c[i+j]=(_c[i+j]+a[i]*b[j])%mod;
for (int i=k+k-1;i>=k;i--) if (_c[i])
rep(j,0,SZ(Md)) _c[i-k+Md[j]]=(_c[i-k+Md[j]]-_c[i]*_md[Md[j]])%mod;
rep(i,0,k) a[i]=_c[i];
}
int solve(ll n,VI a,VI b) { // a 系数 b 初值 b[n+1]=a[0]*b[n]+...
ll ans=0,pnt=0;
int k=SZ(a);
assert(SZ(a)==SZ(b));
rep(i,0,k) _md[k-1-i]=-a[i];_md[k]=1;
Md.clear();
rep(i,0,k) if (_md[i]!=0) Md.push_back(i);
rep(i,0,k) res[i]=base[i]=0;
res[0]=1;
while ((1ll<<pnt)<=n) pnt++;
for (int p=pnt;p>=0;p--) {
mul(res,res,k);
if ((n>>p)&1) {
for (int i=k-1;i>=0;i--) res[i+1]=res[i];res[0]=0;
rep(j,0,SZ(Md)) res[Md[j]]=(res[Md[j]]-res[k]*_md[Md[j]])%mod;
}
}
rep(i,0,k) ans=(ans+res[i]*b[i])%mod;
if (ans<0) ans+=mod;
return ans;
}
VI BM(VI s) {
VI C(1,1),B(1,1);
int L=0,m=1,b=1;
rep(n,0,SZ(s)) {
ll d=0;
rep(i,0,L+1) d=(d+(ll)C[i]*s[n-i])%mod;
if (d==0) ++m;
else if (2*L<=n) {
VI T=C;
ll c=mod-d*powmod(b,mod-2,mod)%mod;
while (SZ(C)<SZ(B)+m) C.pb(0);
rep(i,0,SZ(B)) C[i+m]=(C[i+m]+c*B[i])%mod;
L=n+1-L; B=T; b=d; m=1;
} else {
ll c=mod-d*powmod(b,mod-2,mod)%mod;
while (SZ(C)<SZ(B)+m) C.pb(0);
rep(i,0,SZ(B)) C[i+m]=(C[i+m]+c*B[i])%mod;
++m;
}
}
return C;
}
int gao(VI a,ll n) {
VI c=BM(a);
c.erase(c.begin());
rep(i,0,SZ(c)) c[i]=(mod-c[i])%mod;
return solve(n,c,VI(a.begin(),a.begin()+SZ(c)));
}
};
//扩展GCD
int ex_gcd(int a,int b,int &x,int &y){
if(b==0){x = 1;y = 0;return a;}
int g = ex_gcd(b,a%b,x,y);
int temp = x;
x = y;
y = temp - a/b*y;
return g;
}
//扩展欧几里得的另一种写法
void ex_gcd(int a,int b,int &d,int &x,int &y){
//求解ax+by=gcd(a,b)的一组解
if(!b){
d=a,x=1,y=0;
}
else{
ex_gcd(b,a%b,d,y,x);
y-=x*(a/b);
}
}
//逆元
int inv(int a,int mod){
int X,Y;
int g = ex_gcd(a,mod,X,Y);
if(g!=1)return -1;
return (X%mod + mod)%mod;
}
int a[maxn];
int sum[maxn];
signed main() {
/*push_back 进去前 8~10 项左右、最后调用 gao 得第 n 项*/
int T;
scanf("%d",&T);
while(T--){
vector<int>v;
scanf("%lld%lld",&k,&n);
int invk=inv(k,mod);
if(n==-1){
int tmp=inv(k+1,mod);
printf("%lld\n",2*tmp%mod);
continue;
}
a[0]=1;
for(int i=1;i<=50;i++){
a[i]=0;
for(int j=1;j<=min(i,k);j++){
a[i]+=a[i-j]*invk%mod;
a[i]%=mod;
}
}
for(int i=1;i<=50;i++){
v.push_back(a[i]);
}
printf("%lld\n",linear_seq::gao(v,n-1)%mod);
}
return 0;
}
这个题就往里面扔了2*k+2个数
自适应辛普森公式求数值积分
//黑匣子调用:
//先修改函数 double F(double x){}
//然后ans = ars(a, b, eps);
double F(double x){
return 1;
}
double simpson(double a, double b){
double c = a + (b-a)/2.0;
return (F(a) +4*F(c) + F(b)) * (b-a) / 6.0;
}
double asr(double a, double b, double eps, double A){
double c = a + (b-a) / 2.0;
double L = simpson(a, c), R = simpson(c, b);
if(fabs(L+R-A) <= 15*eps) return L+R+(L+R-A)/15.0;
return asr(a, c, eps/2.0, L) + asr(c, b, eps/2.0, R);
}
double asr(double a, double b, double eps){
return asr(a, b, eps, simpson(a,b));
}
莫比乌斯函数和它的前缀和
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <iostream>
#include <cmath>
#include <queue>
#include <vector>
#include <iomanip>
#define int long long
using namespace std;
const int maxn=1e5+10;
int vis[maxn];
int prime[maxn],tot;
int mu[maxn];//莫比乌斯函数
int sum[maxn];//莫比乌斯函数前缀和
void init(){
memset(vis,0,sizeof(vis));
tot=0;
mu[1]=1;
for(int i=2;i<maxn;i++){
if(!vis[i]){
prime[++tot]=i;
mu[i]=-1;//素数的话就是-1
}
for(int j=1;j<=tot;j++){
if(i*prime[j]>=maxn){
break;
}
vis[i*prime[j]]=1;
if(i%prime[j]==0){
mu[i*prime[j]]=0;
break;
}
else{
mu[i*prime[j]]=-mu[i];//多了个质因子,多个-1
}
}
}
sum[0]=0;
for(int i=1;i<maxn;i++){
sum[i]=sum[i-1]+mu[i];
}
}
大质数的质因子分解——Pollard_rho算法
#include <cstdio>
#include <cstring>
#include <cmath>
#include <ctime>
#include <iostream>
#include <algorithm>
#include <bits/stdc++.h>
#include <unordered_map>
using namespace std;
typedef unsigned long long LL;
std::mt19937 mt_rd(std::chrono::system_clock::now().time_since_epoch().count());//дицК
const LL NUM=10;//运算次数,Miller_Rabin算法为概率运算,误判率为2^(-NUM);
unordered_map<LL,int> mp;
int num[100];
LL t,f[100];
/*
struct ios {
inline char read(){
static const int IN_LEN=1<<18|1;
static char buf[IN_LEN],*s,*t;
return (s==t)&&(t=(s=buf)+fread(buf,1,IN_LEN,stdin)),s==t?-1:*s++;
}
template <typename _Tp> inline ios & operator >> (_Tp&x){
static char c11,boo;
for(c11=read(),boo=0;!isdigit(c11);c11=read()){
if(c11==-1)return *this;
boo|=c11=='-';
}
for(x=0;isdigit(c11);c11=read())x=x*10+(c11^'0');
boo&&(x=-x);
return *this;
}
}io;
*/
LL mul_mod(LL a,LL b,LL n)//求a*b%n,由于a和b太大,需要用进位乘法
{
a=a%n;
b=b%n;
LL s=0;
while(b)
{
if(b&1)
s=(s+a)%n;
a=(a<<1)%n;
b=b>>1;
}
return s;
}
LL pow_mod(LL a,LL b,LL n)//求a^b%n
{
a=a%n;
LL s=1;
while(b)
{
if(b&1)
s=mul_mod(s,a,n);
a=mul_mod(a,a,n);
b=b>>1;
}
return s;
}
bool check(LL a,LL n,LL r,LL s)
{
LL ans,p,i;
ans=pow_mod(a,r,n);
p=ans;
for(i=1;i<=s;i++)
{
ans=mul_mod(ans,ans,n);
if(ans==1&&p!=1&&p!=n-1)return true;
p=ans;
}
if(ans!=1)return true;
return false;
}
bool Miller_Rabin(LL n)//Miller_Rabin算法,判断n是否为素数
{
if(n<2)return false;
if(n==2)return true;
if(!(n&1))return false;
LL i,r,s,a;
r=n-1;s=0;
while(!(r&1)){r=r>>1;s++;}
for(i=0;i<NUM;i++)
{
a=mt_rd()%(n-1)+1;
if(check(a,n,r,s))
return false;
}
return true;
}
LL gcd(LL a,LL b)
{
for(;a>0&&b>0;a>b?a%=b:b%=a);
return a+b;
}
LL Pollard_rho(LL n,LL c)//Pollard_rho算法,找出n的因子
{
LL i=1,j,k=2,x,y,d,p;
x=mt_rd()%n;
y=x;
while(true)
{
i++;
x=(mul_mod(x,x,n)+c)%n;
if(y==x)return n;
if(y>x)p=y-x;
else p=x-y;
d=gcd(p,n);
if(d!=1&&d!=n)return d;
if(i==k)
{
y=x;
k+=k;
}
}
}
void find(LL n)//找出n的所有因子
{
if(Miller_Rabin(n))
{
f[t++]=n;//保存所有因子
return;
}
LL p=n;
while(p>=n)p=Pollard_rho(p,mt_rd()%(n-1)+1);//由于p必定为合数,所以通过多次求解必定能求得答案
find(p);
find(n/p);
}
int main()
{
srand(time(NULL));//随机数设定种子
LL n;
int T,ans;
ios::sync_with_stdio(false),cin.tie(0),cout.tie(0);
cin>>T;
while(T--){
cin>>n;
t=0;
find(n);
sort(f,f+t);
mp.clear();
ans=1000;
for(int i=0;i<t;++i){
mp[f[i]]++;
}
for(int i=0;i<t;++i){
ans=min(ans,mp[f[i]]);
}
cout<<ans<<endl;
}
return 0;
}
欧拉函数前缀和
#include <bits/stdc++.h>
#define int long long
using namespace std;
const int maxn=1e6+10;
int phi[maxn];
int prime[maxn],tot;
int vis[maxn];
void init(){
memset(vis,0,sizeof(vis));
tot=0;
phi[1]=1;
for(int i=2;i<maxn;i++){
if(!vis[i]){
prime[++tot]=i;
phi[i]=i-1;
}
for(int j=1;j<=tot;j++){
if(i*prime[j]>maxn)break;
vis[i*prime[j]]=1;
if(i%prime[j]==0){
phi[i*prime[j]]=phi[i]*prime[j];
break;
}
else{
phi[i*prime[j]]=phi[i]*(prime[j]-1);
}
}
}
}