1 条题解

  • 0
    @ 2023-6-21 19:57:07

    C++ :

    #include <cstdio>
    #include <cstring>
    #include <algorithm>
    #include <cmath>
    using namespace std;
    typedef long long LL;
    const int SIZEN = 10000100;
    int prime[SIZEN],tot = 0;
    LL u[SIZEN];
    LL g[SIZEN],N,M,cnt = 0;
    bool vis[SIZEN]={0};
    struct Hash_Table{
    	static const int SIZE = 1333331;
    	int head[SIZE];
    	int tot;
    	int next[SIZE];
    	LL org[SIZE];
    	LL val[SIZE];
    	void add(LL o,LL v){
    		int k = o % SIZE;
    		tot++;
    		org[tot] = o;val[tot] = v;
    		next[tot] = head[k];
    		head[k] = tot;
    	}
    	bool find(LL o){
    		int k = o % SIZE;
    		for(int i = head[k];i;i=next[i])
    		if(org[i] == o)return true;
    		return false;
    	}
    	LL get(LL o){
    		int k = o % SIZE;
    		for(int i = head[k];i;i=next[i])
    		if(org[i] == o)return val[i];	
    	}
    }ha,sh;
    void Prime(){
    	u[1] = 1;g[1] = 1;
    	for(int i = 2;i <= 10000000;i++){
    		if(!vis[i]){prime[++tot] = i;u[i] = -1;}	
    		for(int j = 1;j <= tot && prime[j]*i <= 10000000;j++){
    			vis[i*prime[j]] = true;
    			if(i % prime[j] == 0){
    				u[i*prime[j]] = 0;
    				break;	
    			}
    			u[i*prime[j]] = -u[i];
    		}
    		g[i] = g[i-1]+(u[i]*u[i]);
    		u[i] = u[i] + u[i-1];
    	}
    }
    LL sumu(LL x){
    	if(x <= 10000000)return u[x];
    	if(sh.find(x))return sh.get(x);
    	LL ret = 0;
    	for(LL i = 2,j;i <= x;i=j+1){
    		j = x/(x/i);
    		ret += (j-i+1)*sumu(x/i);
    	}	
    	ret = 1-ret;
    	sh.add(x,ret);
    	return ret;
    }
    LL Calc(LL x){
    	
    	if(x <= 10000000)return g[x];
    	if(ha.find(x))return ha.get(x);
    	LL ret = 0;
    	for(LL i = 1,j,k;i*i <= x;i=k+1){
    		j = x/(x/(i*i));k = (LL)sqrt(1.*j);
    		ret += x/(i*i)*(sumu(k)-sumu(i-1));
    	}
    	ha.add(x,ret);
    	return ret;
    }
    int main(){
    	Prime();
    	scanf("%lld%lld",&N,&M);//printf("g = %lld %lld\n",Calc(1000000),g[1000000]);
    	if(N > M)swap(N,M);
    	LL ans = 0;
    	for(LL i = 1,j;i <= N;i=j+1){
    		j = min(N/(LL)sqrt(N/i)/(LL)sqrt(N/i),M/(LL)sqrt(M/i)/(LL)sqrt(M/i));
    		ans += (Calc(j)-Calc(i-1))*(LL)sqrt(N/i)*(LL)sqrt(M/i);
    	}
    	//printf("cnt = %lld\n",cnt);
    	printf("%lld\n",ans);
    	return 0;
    }
    
    • 1

    #510. 「邢台编程 NOI Round #1」动态几何问题

    信息

    ID
    990
    时间
    3000ms
    内存
    1024MiB
    难度
    10
    标签
    递交数
    1
    已通过
    0
    上传者