Diorvh

导航

【日记】12.26

12.26

莫反

1.BZOJ2154:求lcm

思路:由lcm=i*j/gcd展开,两次分块,总复杂度\(O(n)\)

#include<bits/stdc++.h>
using namespace std;
const int M=1e7+20,P=20101009;
#define LL long long 
int prime[M],cnt,vis[M],mu[M];
void get(int n){
    mu[1]=1;
    for(int i=2;i<=n;i++){
        if(!vis[i])
            prime[++cnt]=i,mu[i]=-1;
        for(int j=1;j<=cnt&&prime[j]*i<=n;j++){
            vis[i*prime[j]]=1;
            if(i%prime[j]==0)
                break;
            mu[i*prime[j]]=-mu[i];
        }
    }
    for(int i=1;i<=n;++i)
    	mu[i]=1LL*mu[i]*i*i%P;
    for(int i=1;i<=n;++i)
    	mu[i]=(mu[i]+mu[i-1])%P;
}
struct Task{
	int n,m;
	void init(){
		scanf("%d%d",&n,&m);
		get(min(n,m));
	}
	inline LL quad(int n){
		return 1LL*(n+1)*n/2%P;
	}
	inline LL cald(int k,int n,int m){
		LL ans=0;
		for(int l=1,r;l<=k;l=r+1)
			r=min(n/l?min(k,n/(n/l)):k,m/l?min(k,m/(m/l)):k),ans=(ans+1LL*(mu[r]-mu[l-1]+P)%P*quad(n/l)%P*quad(m/l)%P)%P;
		return ans;
	}
	inline LL cald2(int k,int n,int m){
		LL ans=0;
		for(int l=1,r;l<=k;l=r+1)
			r=min(n/l?min(k,n/(n/l)):k,m/l?min(k,m/(m/l)):k),ans=(ans+1LL*(quad(r)-quad(l-1)+P)%P*cald(min(n/l,m/l),n/l,m/l)%P)%P;
		return ans;
	}
	void run(){
		init();
		printf("%lld\n",cald2(min(n,m),n,m));
	}
}t;
int main(){
	t.run();
	return 0;
}

2.BZOJ2693:

#include<bits/stdc++.h>
using namespace std;
const int M=1e7+20,P=1e8+9;
#define LL long long 
int prime[M],cnt,vis[M],mu[M],f[M];
void get(int n){
    mu[1]=f[1]=1;
    for(int i=2;i<=n;i++){
        if(!vis[i])
            prime[++cnt]=i,mu[i]=-1,f[i]=(1-i+P)%P;
        for(int j=1;j<=cnt&&prime[j]*i<=n;j++){
            vis[i*prime[j]]=1;
            if(i%prime[j]==0){
            	f[i*prime[j]]=f[i];
                break;
            }
            mu[i*prime[j]]=-mu[i],f[i*prime[j]]=1LL*f[i]*f[prime[j]]%P;
        }
    }
    for(int i=1;i<=n;++i)
    	f[i]=1LL*f[i]*i%P;
    for(int i=1;i<=n;++i)
    	f[i]=(f[i]+f[i-1])%P;
}
struct Task{
	int n,m;
	void init(){
		scanf("%d%d",&n,&m);
	}
	inline LL quad(int n){
		return 1LL*(n+1)*n/2%P;
	}
	inline LL cald(int k,int n,int m){
		LL ans=0;
		for(int l=1,r;l<=k;l=r+1)
			r=min(n/l?min(k,n/(n/l)):k,m/l?min(k,m/(m/l)):k),ans=(ans+1LL*(f[r]-f[l-1]+P)%P*quad(n/l)%P*quad(m/l)%P)%P;
		return ans;
	}
	void run(){
		init();
		printf("%lld\n",cald(min(n,m),n,m));
	}
}t;
int main(){
	get(1e7);
	int T;
	scanf("%d",&T);
	for(int i=1;i<=T;++i)
		t.run();
	return 0;
}

posted on 2019-12-26 19:44  diorvh  阅读(97)  评论(0编辑  收藏  举报