zoukankan      html  css  js  c++  java
  • BZOJ3944 Sum

    本文版权归ljh2000和博客园共有,欢迎转载,但须保留此声明,并给出原文链接,谢谢合作。

     

    本文作者:ljh2000
    作者博客:http://www.cnblogs.com/ljh2000-jump/
    转载请注明出处,侵权必究,保留最终解释权!

     

     

    Description

    Input

    一共T+1行
    第1行为数据组数T(T<=10)
    第2~T+1行每行一个正整数N,代表一组询问
     

     

     

    Output

    一共T行,每行两个用空格分隔的数ans1,ans2
     

     

    Sample Input

    6
    1
    2
    8
    13
    30
    2333

    Sample Output

    1 1
    2 0
    22 -2
    58 -3
    278 -3
    1655470 2
     
     
    正解:线性筛+杜教筛
    解题报告:
      这道题是杜教筛模板题,在笔记本上推了两遍才开始写......
      

      显然后面那一坨可以记忆化搜索。

      另外因为无法用数组存下来(此时$frac{n}{i}$大于等于$n^{frac{2}{3}}$),所以我们考虑用分子(即$i$,显然小于等于$n^{frac{1}{3}}$)表示这个分数所代表的欧拉函数前缀和,即可避开存不下的尴尬问题。  

      ps:我讨厌$2^{31}-1$!!!!!!!!看看我代码中的unsigned int就懂了。
      
     
    //It is made by ljh2000
    #include <iostream>
    #include <cstdlib>
    #include <cstring>
    #include <cstdio>
    #include <cmath>
    #include <algorithm>
    using namespace std;
    typedef long long LL;
    typedef unsigned int uint;
    const int MAXN = 5400011;
    const int m = 5400000;
    const int MAXM = 100011;
    int n,prime[MAXN],cnt;
    LL mobius[MAXN],phi[MAXN];
    LL ans_phi[MAXM],ans_mo[MAXM];
    bool vis[MAXN],visp[MAXM],vism[MAXM];
    inline int getint(){
        int w=0,q=0; char c=getchar(); while((c<'0'||c>'9') && c!='-') c=getchar();
        if(c=='-') q=1,c=getchar(); while (c>='0'&&c<='9') w=w*10+c-'0',c=getchar(); return q?-w:w;
    }
    
    inline void init(){
    	mobius[1]=1; phi[1]=1;
    	for(int i=2;i<=m;i++) {
    		if(!vis[i]) { prime[++cnt]=i; mobius[i]=-1; phi[i]=i-1; }
    		for(int j=1;j<=cnt && (LL)i*prime[j]<=m;j++) {
    			vis[i*prime[j]]=1;
    			if(i%prime[j]==0) { phi[i*prime[j]]=phi[i]*prime[j]; mobius[i*prime[j]]=0; break; }
    			else { phi[i*prime[j]]=phi[i]*phi[prime[j]]; mobius[i*prime[j]]=-mobius[i]; }
    		}
    	}
    	for(int i=2;i<=m;i++) mobius[i]+=mobius[i-1],phi[i]+=phi[i-1];
    }
    
    inline LL get_phi(uint now){
    	if(now<=m) return phi[now];
    	int nn=n/now,nex; if(visp[nn]) return ans_phi[nn];
    	LL sav=(LL)now*(now+1)>>1;  
    	for(uint i=2;i<=now;i=nex+1) {
    		nex=now/(now/i);
    		sav-=get_phi(now/i/*!!!*/)*(nex-i+1);
    	}
    	visp[nn]=1;
    	ans_phi[nn]=sav;
    	return sav;
    }
    
    inline LL get_mo(uint now){
    	if(now<=m) return mobius[now];
    	int nn=n/now,nex; if(vism[nn]) return ans_mo[nn];
    	LL sav=1;
    	for(uint i=2;i<=now;i=nex+1) {
    		nex=now/(now/i);
    		sav-=get_mo(now/i/*!!!*/)*(nex-i+1);
    	}
    	vism[nn]=1;/*!!!*/
    	ans_mo[nn]=sav;
    	return sav;
    }
    
    inline void work(){
    	int T=getint(); init(); 
    	while(T--) {
    		n=getint(); memset(visp,0,sizeof(visp)); memset(vism,0,sizeof(vism));
    		LL ans1=get_phi(n); LL ans2=get_mo(n);
    		printf("%lld %lld
    ",ans1,ans2);	   
    	}
    }
    
    int main()
    {
        work();
        return 0;
    }
    

      

     
     
  • 相关阅读:
    Android 11 的5个新安全和隐私功能,不更新会面临被黑客入侵风险
    SSL / TLS新加密漏洞,黑客是这样读取敏感数据,看看修复方法!
    蓝牙新漏洞,黑客可以轻松控制你的手机,全球数亿台设备受影响
    Visa信用卡漏洞,新的PIN验证黑客可绕过,并进行非接触式付款
    思科是如何遭黑客入侵?原因:XSS缺陷到RCE缺陷
    WhatsApp现神秘漏洞,黑客可远程查看聊天记录
    郭盛华:免受网络黑客攻击的5个技巧
    Apache服务器现3个致命漏洞,黑客可远程监听
    centos 下安装python3 的MySQLdb
    MySQL创建用户与授权及删除
  • 原文地址:https://www.cnblogs.com/ljh2000-jump/p/6250578.html
Copyright © 2011-2022 走看看