POJ-2773 2分夹逼+DFS解容斥..

      有了DFS解容斥问题的思路..这题不难想...若一个数x与所给的m互质..则说明x与h的GCD==1...将m因式分解,对于一个确定的上限...可以通过DFS对这些质因数解容斥求出当前上限下有多少个与m不互质的数...从而又能得到当前上限下有多少个与m互质的数...

      想到了这一步..就不难想到2的思路了...通过2分夹逼找到所需的数...并且数据范围m<=100000..在这个范围内因式分解..最多也不会超过6个质因数.{2,3,5,7,11,13}已经超过100000..显然时间上是绝对能秒杀的...

 

Program:

#include<iostream>
#include<string.h>
#include<stdio.h>
#define ll long long
using namespace std;
ll n,m,a[25],ans,p,t,h,l,r,mid; 
void DFS(ll i,ll w,ll k)
{      
       for (;i<=n;i++)
       if (a[i])
       {
             p=a[i]*w;
             h+=k*(mid/p);
             DFS(i+1,p,-k);
       }
       return;
}
int main()
{
       ll i;
       while (cin>>m>>t)
       { 
             n=0;
             for (i=2;i<=m;i++)
             if (m%i==0)
             {
                   while (m%i==0) m/=i;
                   a[++n]=i;
                   if (m==1) break;
             } 
             r=1;
             while (1)
             {
                   mid=r;
                   h=0;
                   DFS(1,1,1);
                   if (mid-h<t) r*=2;
                     else break;
             }
             l=1;
             while (r-l>1)
             {
                   mid=(l+r)/2;
                   h=0;
                   DFS(1,1,1);
                   if (mid-h>=t) r=mid;
                     else l=mid;
             }
             cout<<r<<endl;
       }
       return 0;
}


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值