【2020省选模拟】题解

T1:

直接求 ≤ k \le k k的答案
就是 n ! [ x n ] ( ∑ i = 0 k x i i ! ) m n![x^n](\sum_{i=0}^k\frac{x^i}{i!})^m n![xn](i=0ki!xi)m
暴力 ln ⁡ , exp ⁡ \ln,\exp ln,exp即可 O ( n 3 ) O(n^3) O(n3)

#include<bits/stdc++.h>
using namespace std;
#define cs const
#define pb push_back
#define pii pair<int,int>
#define fi first
#define se second
#define ll long long 
#define bg begin

namespace IO{

cs int rlen=1<<22|1;
char ibuf[rlen],*ib,*ob;
inline char gc(){
	(ib==ob)&&(ob=(ib=ibuf)+fread(ibuf,1,rlen,stdin));
	return (ib==ob)?EOF:*ib++;
}
inline int read(){
	char ch=gc();
	int res=0;bool f=0;
	while(!isdigit(ch))f=ch=='-',ch=gc();
	while(isdigit(ch))res=(res*10)+(ch^48),ch=gc();
	return f?-res:res;
}

}
using IO::read;
template<typename tp>inline void chemx(tp &a,tp b){(a<b)?(a=b):0;}
template<typename tp>inline void chemn(tp &a,tp b){(a>b)?(a=b):0;}

int mod;ll r;
inline int add(int a,int b){return a+b>=mod?a+b-mod:a+b;}
inline int dec(int a,int b){return a<b?a-b+mod:a-b;}
inline int mul(int a,int b){r=(ll)a*b;return r>=mod?r%mod:r;}
inline void Add(int &a,int b){a=a+b>=mod?a+b-mod:a+b;}
inline void Dec(int &a,int b){a=a<b?a-b+mod:a-b;}
inline void Mul(int &a,int b){r=(ll)a*b;a=r>=mod?r%mod:r;}
inline int ksm(int a,int b,int res=1){for(;b;b>>=1,Mul(a,a))if(b&1)Mul(res,a);return res;}
inline int Inv(int x){return ksm(x,mod-2);}

cs int N=505;
int n,m,fac[N],ifac[N],iv[N+N];
inline void init_fac(){
	fac[0]=ifac[0]=1;
	for(int i=1;i<N;i++)fac[i]=mul(fac[i-1],i);
	ifac[N-1]=Inv(fac[N-1]);
	for(int i=N-2;i;i--)ifac[i]=mul(ifac[i+1],i+1);
	iv[0]=iv[1]=1;
	for(int i=2;i<N+N;i++)iv[i]=mul(mod-mod/i,iv[mod%i]);
}
int f[N];
int a[N+N],b[N+N];
inline void Ln(int *a,int deg){
	b[0]=0;
	for(int i=1;i<deg;i++){
		int nw=mul(a[i],i);
		for(int j=1;j<i;j++)Dec(nw,mul(b[j],a[i-j]));
		b[i]=nw;
	}
	for(int i=0;i<deg;i++)a[i]=mul(b[i],iv[i]);
}
inline void Exp(int *a,int deg){
	b[0]=1;
	for(int i=0;i<deg;i++)Mul(a[i],i);
	for(int i=1;i<deg;i++){
		int nw=0;
		for(int j=0;j<i;j++)Add(nw,mul(b[j],a[i-j]));
		b[i]=mul(nw,iv[i]);
	}
	for(int i=0;i<deg;i++)a[i]=b[i];
}
inline int calc(int k){
	for(int i=0;i<=k;i++)a[i]=ifac[i];
	for(int i=k+1;i<=n;i++)a[i]=0;
	Ln(a,n+1);
	for(int i=0;i<=n;i++)Mul(a[i],m);
	Exp(a,n+1);
	return mul(a[n],fac[n]);
}
int main(){
	n=read(),m=read(),mod=read();
	init_fac();
	for(int i=1;i<=n;i++)f[i]=calc(i);
	for(int i=n;i;i--)Dec(f[i],f[i-1]);
	for(int i=1,mt=Inv(ksm(m,n));i<=n;i++)Mul(f[i],mt);
	for(int i=1;i<=n;i++)cout<<f[i]<<" ";puts("");
	return 0;
}

T2:

可以推得
l c m ( i , j , i + j ) = i ∗ j ∗ ( i + j ) / g c d ( i , j ) 2 lcm(i,j,i+j)=i*j*(i+j)/gcd(i,j)^2 lcm(i,j,i+j)=ij(i+j)/gcd(i,j)2

然后简单莫反

a n s = ∑ T = 1 L f ( T ) g ( n T , m T ) ans=\sum_{T=1}^Lf(T)g(\frac{n}{T},\frac m T) ans=T=1Lf(T)g(Tn,Tm)
f = ( μ × I d 3 ) ∗ I d , g ( n , m ) = ∑ i = 1 n ∑ j = 1 m i 2 j + i j 2 f=(\mu \times Id^3)*Id,g(n,m)=\sum_{i=1}^n\sum_{j=1}^mi^2j+ij^2 f=(μ×Id3)Idg(n,m)=i=1nj=1mi2j+ij2
只需要 f ∗ I d 3 f*Id^3 fId3构造杜教筛即可

#include<bits/stdc++.h>
using namespace std;
#define cs const
#define pb push_back
#define pii pair<int,int>
#define fi first
#define se second
#define ll long long
#define bg begin

namespace IO{

cs int rlen=1<<22|1;
char ibuf[rlen],*ib,*ob;
inline char gc(){
	(ib==ob)&&(ob=(ib=ibuf)+fread(ibuf,1,rlen,stdin));
	return (ib==ob)?EOF:*ib++;
}
inline int read(){
	char ch=gc();
	int res=0;bool f=0;
	while(!isdigit(ch))f=ch=='-',ch=gc();
	while(isdigit(ch))res=(res*10)+(ch^48),ch=gc();
	return f?-res:res;
}
inline ll readll(){
	char ch=gc();
	ll res=0;bool f=0;
	while(!isdigit(ch))f=ch=='-',ch=gc();
	while(isdigit(ch))res=(res*10)+(ch^48),ch=gc();
	return f?-res:res;	
}

}
using IO::read;
using IO::readll;

template<typename tp>inline void chemx(tp &a,tp b){(a<b)?(a=b):0;}
template<typename tp>inline void chemn(tp &a,tp b){(a>b)?(a=b):0;}

cs int mod=1e9+7;
inline int add(int a,int b){return a+b>=mod?a+b-mod:a+b;}
inline int dec(int a,int b){return a<b?a-b+mod:a-b;}
inline int mul(int a,int b){return (ll)a*b%mod;}
inline void Add(int &a,int b){a=a+b>=mod?a+b-mod:a+b;}
inline void Dec(int &a,int b){a=a<b?a-b+mod:a-b;}
inline void Mul(int &a,int b){a=(ll)a*b%mod;}
inline int ksm(int a,int b,int res=1){for(;b;b>>=1,Mul(a,a))if(b&1)Mul(res,a);return res;}
inline int Inv(int x){return ksm(x,mod-2);}
inline int fix(ll x){return x>=mod?x%mod:x;}
void fip(int &x){x<0?x+=mod:0;}
int iv2=Inv(2),iv6=Inv(6);
inline int P(int x){return mul(x,x);}
inline int S1(ll x){x=fix(x);return ((x*(x+1))>>1)%mod;}
inline int S2(ll x){x=fix(x);return mul(x,mul(x+1,mul(2*x+1,iv6)));}
inline int S3(ll x){x=fix(x);return P(S1(x));}

cs int N=5000005;
int pr[N/10],tot,mu[N],f[N],g[N];
bool vis[N];
inline void init_sieve(cs int n=N-1){
	mu[1]=g[1]=1;
	for(int i=2;i<=n;i++){
		if(!vis[i])pr[++tot]=i,mu[i]=mod-1;
		g[i]=mul(mu[i],mul(i,i));
		for(int j=1,p;j<=tot&&i*pr[j]<=n;j++){
			p=i*pr[j];
			vis[p]=1;
			if(i%pr[j]==0)break;
			mu[p]=mod-mu[i];
		}
	}
	for(int i=1;i<=tot;i++)for(int j=1;j*pr[i]<=n;j++)Add(g[j*pr[i]],g[j]);
	for(int i=1;i<=n;i++)g[i]=add(mul(g[i],i),g[i-1]);
}
struct Map{
	static cs int mod=19260817,N=2e6+5;
	int adj[mod],nxt[N],vl[N],cnt;ll to[N];
	void insert(ll x,int k){
		int p=x%mod;
		nxt[++cnt]=adj[p],adj[p]=cnt,vl[cnt]=k,to[cnt]=x;
	}
	int find(ll x){
		int p=x%mod;
		for(int e=adj[p];e;e=nxt[e])if(to[e]==x)return vl[e];
		return -1;
	}
}vs;
inline int S(ll x){
	if(x<N)return g[x];
	int t;
	if((t=vs.find(x))!=-1)return t;
	int res=S1(x);
	for(ll l=2,r,t,pre=1,now;l<=x;l=r+1){
		t=x/l;
		r=(x/t);now=S3(r);
		Dec(res,mul(dec(now,pre),S(t)));
		pre=now;
	}vs.insert(x,res);
	return res;
}
inline int F(ll n,ll m){
	return add(mul(S1(n),S2(m)),mul(S2(n),S1(m)));
}
ll n,m;
int main(){
	init_sieve();
	n=readll(),m=readll();
	if(n>m)swap(n,m);int res=0;
	for(ll l=1,r,pre=0,a,b,now;l<=n;l=r+1){
		a=n/l,b=m/l;
		r=min(n/a,m/b);
		now=S(r);
		Add(res,mul(dec(now,pre),F(a,b)));
		pre=now;
	}cout<<res<<'\n';
	return 0;
}

T3:

支持集合合并,第k小,可持久化

发现神tm卡空间,离线后平衡树空间会炸裂
于是你用bitset即可
简直有毒

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值