zoukankan      html  css  js  c++  java
  • 并不对劲的bzoj1853:[SCOI2010]幸运数字

    传送门->

    据说本题的正确读法是【shìng运数字】。

    听上去本题很适合暴力,于是并不对劲的人就去写了。其实这题就是一个很普(有)通(趣)暴力+神奇的优化。

    首先,会发现幸运数字很少,那么就先搜索出所有幸运数字。

    找出每个幸运数字后,会发现每一个数在[a,b]出现了多少次是可以直接算出的,就是floor(b/x)-ceil(a/x)+1。

    但是直接加想必是不行的,因为两个数的lcm被算重复了。这时直接容斥会不会T或者出一些奇怪的问题?当然会。所以不能直接容斥,要加些优化再容斥。

    1.有些幸运数字是其它幸运数字的倍数,要它何用?

    2.当lcm>b时,[a,b]中肯定没有lcm的倍数,要剪掉。

    3.lcm(x,y)=x*y/gcd(x,y),会发现x*y可能会爆long long,用double来存。

    #include<algorithm>
    #include<cmath>
    #include<cstdio>
    #include<cstdlib>
    #include<cstring>
    #include<iomanip>
    #include<iostream>
    #include<map>
    #include<queue>
    #include<stack>
    #include<vector>
    #define rep(i,x,y) for(register LL i=(x);i<=(y);++i)
    #define dwn(i,x,y) for(register LL i=(x);i>=(y);--i)
    #define re register
    #define LL long long
    #define LCM(x,y) ((x)*(y)/gcd((x),(y)))
    using namespace std;
    inline LL read()
    {
        LL x=0,f=1;
        char ch=getchar();
        while(isdigit(ch)==0 && ch!='-')ch=getchar();
        if(ch=='-')f=-1,ch=getchar();
        while(isdigit(ch))x=x*10+ch-'0',ch=getchar();
        return x*f;
    }
    inline void write(LL x)
    {
        LL f=0;char ch[20];
        if(!x){puts("0");return;}
        if(x<0){putchar('-');x=-x;}
        while(x)ch[++f]=x%10+'0',x/=10;
        while(f)putchar(ch[f--]);
        putchar('
    ');
    }
    LL ten[15],a,b,luck[8200],ans,inf[3];
    int lena,lenb,cnt,tim;
    int getten(LL x){rep(i,0,10)if(ten[i]<=x&&ten[i+1]>x)return i;}
    void reset(){ten[0]=1;rep(i,1,11)ten[i]=ten[i-1]*10;}
    void force(int x,int tot,LL tmp)
    {
    	tim++;
    	if(x==tot+1){/*cout<<"+"<<endl;*/luck[++cnt]=tmp;return;}
    	force(x+1,tot,tmp+6*ten[x]),force(x+1,tot,tmp+8*ten[x]);
    }
    LL gcd(LL x,LL y)
    {
    	if(x>y)swap(x,y);
    	if(x==0)return y;
    	return gcd(y%x,x);
    }
    void search(int x,int step,LL lcm)
    {
    	if(lcm>b)return;
    	if(step==cnt){if(!x)return;ans+=(x&1?1:-1)*(((b/lcm)-(a+lcm-1)/lcm)+1);return;}
    	search(x,step+1,lcm);
    	LL tmp=lcm/gcd(lcm,luck[step+1]);
    	if(1.0*tmp*luck[step+1]<=b)
    	search(x+1,step+1,tmp*luck[step+1]);
    }
    bool cmp(LL x,LL y){return x>y;}
    int main()
    {
        memset(inf,0x7f,sizeof(inf));
        reset();
        a=read(),b=read();
        lenb=getten(b);
    	rep(i,0,lenb)
        	force(0,i,0);
        //	cout<<tim<<endl;
        sort(luck+1,luck+cnt+1,cmp);
        rep(i,1,cnt)
         if(luck[i]!=-inf[0]) 
            rep(j,i+1,cnt)
               if(luck[j]!=-inf[0]&&luck[i]%luck[j]==0)luck[i]=-inf[0];
        luck[cnt+1]=-inf[0];
        sort(luck+1,luck+cnt+1,cmp);
      //  rep(i,1,cnt)cout<<luck[i]<<endl; 
        cnt=0;
        while(luck[cnt+1]!=-inf[0])cnt++;
    //	cout<<"shing"<<endl;
     	search(0,0,1);
    	write(ans);
    	return 0;
    }
    //1 10000000000
    

     并不对劲的暴力选手表示写完后身心愉悦。

  • 相关阅读:
    Dual Quaternion Knowledge Graph Embeddings——对偶四元数知识图谱嵌入
    Python argparse模块
    Pythonvirtualenv创建虚拟环境
    KBGAN:用于知识图谱嵌入的对抗学习
    anaconda简单使用
    二分查找详解
    Quaternion Knowledge Graph Embeddings —— 基于四元数的知识图谱嵌入
    ConvR——用于多关系学习的自适应卷积模型
    Under Any Linux: install bypy tool
    PRUNE_BIND_MOUNTS="yes"不好用, 什么原因呢?
  • 原文地址:https://www.cnblogs.com/xzyf/p/8709103.html
Copyright © 2011-2022 走看看