数学专题B1—同余

ooliver OI

数学专题B1—同余

P3935 Calculating

设 g(x)=∑i=1xf(i), ∴∑i=lrf(i)=g(r)-g(l-1), 对于 g(x), 枚举每一个因数出现的次数,并按照次数分块, 所以可以得到以下代码:

#include
using namespace std;
#define int long long
const int mod=998244353;
int L,R;
int g(int x){
	int ans=0,l=1;
	while(l>L>>R;
    cout
`#include
using namespace std;
#define int long long
const int mod=998244353;
int L,R;
int g(int x){
	int ans=0,l=1;
	while(l
    	int t=x/l,r=(t==0?x:min(x/t,x));
    	(ans+=(r-l+1)*t)%=mod;
    	l=r+1;
  	}
  	return ans;
}
signed main(){
    cin>>L>>R;
    coutg(R)-g(L-1)+mod)%mod;
  	return 0;
} `

P2312 解方程

注意到 ai 十分巨大, 可以想到等式左边和哈希很相似(就差取模了), 所以我们可以快读,读入时取模。 然后直接暴力即可。 代码:

#include
using namespace std;
#define int long long
const int mod=1e9+7,N=105,M=1e6+5;
int n,m,idx;
int a[N],p[N],ans[M];
int read(){
    int k=0,f=1;
    char c=getchar();
    while(c'9'){
        if(c=='-') f=-1;
        c=getchar();
    }
    while(c>='0'&&c>n>>m;
	for(int i=0;i
`#include
using namespace std;
#define int long long
const int mod=1e9+7,N=105,M=1e6+5;
int n,m,idx;
int a[N],p[N],ans[M];
int read(){
    int k=0,f=1;
    char c=getchar();
    while(c'0'||c>'9'){
        if(c=='-') f=-1;
        c=getchar();
    }
    while(c>='0'&&c'9') k=(k*10+c-'0')%mod,c=getchar();
    return k*f;
}
signed main(){
	cin>>n>>m;
	for(int i=0;ia[i]=read();
	p[0]=1;
	for(int x=1;x
		int now=a[0];
		for(int i=1;ip[i]=(p[i-1]*x)%mod,(now+=a[i]*p[i])%=mod;
		if(now%mod==0) ans[++idx]=x;
	}
	cout
	for(int i=1;ians[i]
	return 0;
}`

P2424 约数和

观察到 f(x)=σ(x), 不妨设 g(x)=∑i=1xσ(i), 所以 f(X)+f(X+1)+......+f(Y)=g(Y)-g(X-1)。 对于 g(x), 同样枚举因数同时按数量分块,统计答案即可。 代码:

#include
using namespace std;
#define int long long
int L,R;
int g(int x){
	int ans=0,l=1;
	while(l>L>>R;
	cout
`#include
using namespace std;
#define int long long
int L,R;
int g(int x){
	int ans=0,l=1;
	while(l
    	int t=x/l,r=(t==0?x:min(x/t,x));
    	ans+=(l+r)*(r-l+1)/2*t;
    	l=r+1;
  	}
  	return ans;
}
signed main(){
	cin>>L>>R;
	coutg(R)-g(L-1);
  	return 0;
} `

P4863 JerryC Loves Driving

amp;∑i=AB∑j=1i⌊ij⌋×(-1)j=amp;∑j=1B(-1)j·∑i=AB⌊ij⌋=amp;∑j=1B(-1)j·(∑i=1B⌊ij⌋-∑i=1A-1⌊ij⌋) 设 g(x,t)=∑i=1x⌊it⌋, 那么可以发现一个规律:

  • 数列的前 t-1 个数一定是0

  • 数列的结尾数字是 (x-t+1)/t,数量为 (x-t+1)[PARSE ERROR: Undefined("Command(\"mod\")")]t。

  • 数列中间数字每个数都连续出现 t 次。

所以可以根据规律 O(1) 求得 g(x,t)。 最终复杂度为 O(B),代码如下:

#include
using namespace std;
#define int long long
int a,b,ans;
int g(int x,int t){
	if(x>a>>b;
	for(int i=1;i
`#include
using namespace std;
#define int long long
int a,b,ans;
int g(int x,int t){
	if(x1) return 0;
	int ed=(x-t+1)/t;
	return ed*(ed+1)/2*t+(x-t+1)%t*(ed+1);
}
signed main(){
	cin>>a>>b;
	for(int i=1;i2?-1:1)*(g(b,i)-g(a-1,i));
	cout
	return 0;
} `