zoukankan      html  css  js  c++  java
  • SPOJ_VLATTICE

    题目是给你一个空间,和一个点(n,n,n),求从原点出发能够直接接触多少个点(不经过任何一个点)?

    典型的mobius反演即可。

    首先,ans=3,因为(1,0,0),(0,1,0),(0,0,1)这三个点必看。

    其次别在三个平面内反演一次,算出三个坐标轴面的可见点数。

    最后在空间反演一次,即可。反演的方法都是分块即可。

     

    召唤代码君:

     

     

    #include <iostream>
    #include <cstdio>
    #include <cstring>
    #define maxn 1001000
    typedef long long ll;
    using namespace std;
    
    int mu[maxn],smu[maxn],pri[maxn];
    ll n;
    ll f[maxn],g[maxn];
    
    void getprim_mu()
    {
    	for (int i=1; i<maxn; i++) mu[i]=1;
    	for (int i=2; i<maxn; i++)
    	{
    		if (pri[i]) continue;
    		mu[i]=-mu[i];
    		for (int j=i+i; j<maxn; j+=i) pri[j]=1,mu[j]=-mu[j];
    		if (maxn/i>=i) for (int j=i*i; j<maxn; j+=i*i) mu[j]=0;
    	}
    	for (int i=1; i<maxn; i++) smu[i]=smu[i-1]+mu[i];
    }
    
    ll getnum(ll N)
    {
    	int next;
    	ll ans=0;
    	for (int i=1; i<=N; i=next+1)
    	{
    		next=N/(N/i);
    		ans+=(smu[next]-smu[i-1])*(N/i)*(N/i);
    	}
    	return ans;
    }
    
    void _init()
    {
    	scanf("%lld",&n);
    	f[1]=getnum(n);
    }
    
    int gcd(int A,int B) { return B==0?A:gcd(B,A%B); }
    
    int main()
    {
    	getprim_mu();
    	int T;
    	ll ans;
    	scanf("%d",&T);
    	while (T--)
    	{
    		_init();
    		ans=3+3*f[1];  
    		for (int i=1,next; i<=n; i=next+1) 
    		{
    			next=n/(n/i);
    			ans+=(n/i)*(n/i)*(n/i)*(smu[next]-smu[i-1]);
    		}
    		printf("%lld
    ",ans);
    	}
    	return 0;
    }
    

      

    如有转载,请注明出处(http://www.cnblogs.com/lochan)
  • 相关阅读:
    【jQuery】清空表单内容
    【jQuery】remove()和empty()的使用
    【ajax 提交表单】多种方式的注意事项 ,serialize()的使用
    【Gson】互相转化
    yum安装nginx详解
    linux find命令
    nginx实战
    java判断是否为汉字
    分布式存储 CentOS6.5虚拟机环境搭建FastDFS-5.0.5集群(转载)
    Java应用程序实现屏幕的"拍照"
  • 原文地址:https://www.cnblogs.com/lochan/p/3840622.html
Copyright © 2011-2022 走看看