BZOJ2988 : DIVISORS

令$NX=PQ$,其中$N

枚举最大的$Q$,那么$NX$要是$Q$和$X$的倍数,且不是$Q+1,Q+2,...,X-1$的倍数。

考虑容斥原理,指数级枚举$NX$一定是$Q+1$到$X-1$这些数中哪些数的倍数,剩下的不管,则对答案的贡献为$(-1)^{打破的限制数量}\lfloor\frac{BQ}{lcm}\rfloor$。

注意到$1..60$在$6\times 10^{13}$范围内的$lcm$数量不多(只有大约一百多万个),将容斥中的指数级枚举换成DP:

设$f[i][j]$表示考虑了$i$到$X-1$,被打破的限制的$lcm=j$的方案数乘以容斥系数之和,然后直接转移即可。

注意精细地实现做到$O(1)$转移,比如通过质因数分解来去掉求$lcm$的$O(\log X)$复杂度。

 

#include
#include
using namespace std;
typedef long long ll;
const int N=65,M=219,K=8197;
int Case,X,S,i,j,k,x,y,z;ll B,lim,ans;
int id[6][4][3][3],cnt,g[M],va[M],p2[9],p3[9],p5[9],p7[9];
int p[N],tot,all;
ll f[M][K],vb[K],_vb[K];
int q[K],at[K],to[K],en[N][M],r;
inline bool isprime(int x){
  for(int i=2;i=11;i--)if(isprime(i))p[tot++]=i;
    for(S=0;S<1<>i&1){
        t*=p[i];
        if(t>lim)break;
      }
      vb[S]=min(t,lim+1);
    }
    all=(1<lim/_vb[k])k--;
          else break;
        }
        en[i][j]=k;
      }
    }
    ans=0;
    S=mask(X);
    for(i=0;i 
 

  

你可能感兴趣的:(BZOJ2988 : DIVISORS)