zoukankan      html  css  js  c++  java
  • Luogu P6583 回首过去 题解

    几亿年没更的博客终于想起来了。。。。

    其实不是我不想更,而是太水了发上去不好意思。。。。

    但是觉得不能辜负zzk巨佬的贴心教导,所以还是写一写吧,毕竟好久没认真学一个新算法了


    题目链接


    首先80分的部分不难想

    对于每一个分母,除去2和5对答案都没有影响,当把所有2、5都除去之后统计即可,复杂度(O(n))

    Code

    #include<bits/stdc++.h>
    #define int long long
    using namespace std;
    
    void file(string s){freopen((s+".in").c_str(),"r",stdin),freopen((s+".out").c_str(),"w",stdout);}
    int read()
    {
    	int a=0,f=1;
    	char ch=getchar();
    	while(ch<'0'||ch>'9'){
    		if(ch=='-')f=-f;
    		ch=getchar();
    	}
    	while(ch>='0'&&ch<='9'){
    		a=a*10+ch-'0';
    		ch=getchar();
    	}
    	return a*f;
    }
    
    int n;
    long long ans;
    
    signed main()
    {
    //	file("");
    	n=read();
    	for(int i=1;i<=n;++i){
    		int x=i;
    		while(!(x%2))x/=2;
    		while(!(x%5))x/=5;
    		ans+=n/x;
    	} 
    	cout<<ans;
    	return 0;
    }
    

    100分部分就用了一些技巧

    首先把这一部分

    while(!(x%2))x/=2;
    while(!(x%5))x/=5;
    ans+=n/x;
    

    改成

    if(i%2==0||i%5==0)continue;
    for(int j=1;j*i<=n;j*=2){
    	for(int k=1;k*i*j<=n;k*=5){
    		tmp++;
    	}
    }
    ans+=n/l*tmp;
    

    也就是把找每个数对应的数是多少变成了算每个数能对应多少个数

    接下来我们就发现只要能优化tmp的求解我们就能进行优化了

    这里用到了整除分块的思想,先把所有因子只有2和5的数从小到大求出来

    void build()
    {
            for(int i=1;i<=n;i*=2){
    	      for(int j=1;j*i<=5;j*=5){
    			num[++tot]=i*j;
    		}
    	}
    	sort(num+1,num+1+tot);
    }
    

    那么对于每一个tmp对应的是哪一个区间就可以求出来

    最后用容斥求一下每个区间有多少个需要统计的数(就是没有被continue的数)就可以了

    复杂度(O(sqrt n))

    Code:

    #include<bits/stdc++.h>
    #define int long long
    using namespace std;
    
    void file(string s){freopen((s+".in").c_str(),"r",stdin),freopen((s+".out").c_str(),"w",stdout);}
    int read()
    {
    	int a=0,f=1;
    	char ch=getchar();
    	while(ch<'0'||ch>'9'){
    		if(ch=='-')f=-f;
    		ch=getchar();
    	}
    	while(ch>='0'&&ch<='9'){
    		a=a*10+ch-'0';
    		ch=getchar();
    	}
    	return a*f;
    }
    
    int n,ans,tot;
    int num[5000];
    
    void build()
    {
    	for(int i=1;i<=n;i*=2){
    		for(int j=1;j*i<=n;j*=5){
    			num[++tot]=i*j;
    		}
    	}
    	sort(num+1,num+1+tot);
    }
    
    int makenum(int l,int r)
    {
    	l--;
    	int num2,num5,num10;
    	num2=r/2-l/2;
    	num5=r/5-l/5;
    	num10=r/10-l/10;
    	return r-l-num2-num5+num10;
    }
    
    int makef(int x)
    {
    	return upper_bound(num+1,num+tot+1,x)-num-1;
    }
    
    signed main()
    {
    //	file("");
    	n=read();
    	build();
    	for(int l=1,r;l<=n;l=r+1){
    		r=n/(n/l);
    		ans+=makef(n/l)*makenum(l,r)*(n/l);
    	}
    	cout<<ans;
    	return 0;
    }
    
    

    orz zzk!

  • 相关阅读:
    向量、矩阵常用范数
    关于HP M451网络连接的资料
    pyqt程序最小化到系统托盘(未测试)
    博客园美化大集合2020最新!不用担心失效问题!
    添加QQ聊天
    关于加密
    python抓取谷歌学术关键词下文章题目
    如何确定网站可否可爬取
    灵狐浏览器
    利用beautifulsoup进行对标签的二次查找-以打印网易云歌单内容为例
  • 原文地址:https://www.cnblogs.com/zhu-chen/p/13043786.html
Copyright © 2011-2022 走看看