zoukankan      html  css  js  c++  java
  • bzoj 1853: [Scoi2010]幸运数字&&2393: Cirno的完美算数教室【容斥原理】

    翻了一些blog,只有我用状压预处理嘛2333,。把二进制位的0当成6,1当成8就行啦。(2393是2和9
    然后( dfs )容斥,加上一个数的( lcm ),减去两个数的( lcm ),加上三个数的( lcm )...需要一些剪枝来控制复杂度。
    剪枝:
    1.对于预处理出来的幸运数字,把倍数都去掉
    2.当( lcm>b )时退出

    注意当选择了0个数时不更新答案。

    #include<iostream>
    #include<cstdio>
    #include<algorithm>
    using namespace std;
    const long long inf=1e18+7;
    long long a,b,p[3005],ans;
    bool cmp(const long long &a,const long long &b)
    {
    	return a>b;
    }
    long long gcd(long long a,long long b)
    {
    	return b==0?a:gcd(b,a%b);
    }
    void dfs(int x,int y,long long z)
    {
    	if(x>p[0])
    	{
    		if(y&1)
    			ans+=((y&1)?1:-1)*(b/z-(a-1)/z);
    		else if(y)
    			ans-=b/z-(a-1)/z;
    		return;
    	}
    	dfs(x+1,y,z);
    	long long tmp=z/gcd(p[x],z);
    	if((double)p[x]*tmp<=b)
    		dfs(x+1,y+1,p[x]*tmp);
    }
    int main()
    {
    	for(long long i=1;i<=10;i++)
    		for(long long j=0;j<(1<<i);j++)
    		{
    			long long now=0ll;
    			for(long long k=1,b=j;k<=i;k++,b>>=1)
    			{
    				if(b&1)
    					now=now*10+8;//9
    				else
    					now=now*10+6;//2
    			}
    			p[++p[0]]=now;
    		}
    	sort(p+1,p+1+p[0]);
    	for(long long i=1;i<=p[0];i++)
    		if(p[i]!=inf)
    			for(long long j=i+1;j<=p[0];j++)
    				if(p[j]%p[i]==0ll)
    					p[j]=inf;
    	sort(p+1,p+1+p[0]);
    	while(p[p[0]]==inf)
    		p[0]--;
    	sort(p+1,p+1+p[0],cmp);
    	scanf("%lld%lld",&a,&b);
    	dfs(1,0,1);
    	printf("%lld
    ",ans);
    	return 0;
    }
    
  • 相关阅读:
    改进的延时函数Delay(使用MsgWaitForMultipleObjects等待消息或超时的到来)
    罗斯福新政
    保存网页为图片——滚动截取IE(WebBrowse)
    Linux LVM硬盘管理及LVM分区扩容
    visual leak dector内存泄漏检测方法
    小智慧30
    函数调用的原理
    HTTP协议漫谈
    Boost源码剖析之:泛型指针类any
    扩展C++ string类
  • 原文地址:https://www.cnblogs.com/lokiii/p/8231335.html
Copyright © 2011-2022 走看看