zoukankan      html  css  js  c++  java
  • SPOJ22549 DIVFACT4


    SP22549 DIVFACT4 - Divisors of factorial (extreme)

    对于每组询问(,)小于(sqrt n)的部分暴力(,)大于(sqrt n)的部分可以数论分块(.)

    问题变为若干个询问区间质数个数的问题(,)且询问端点(() 除了其中最多一个 ()) 都是形如(lfloor frac{n}{i} floor) 的数(,)因此(Min25)筛即可解决(.)

    (O(T(large sqrt{n}+frac{n^{frac{3}{4}}}{log n})))

    注意模数很大(,)要使用快速乘(.)


    代码(:)

    #include <bits/stdc++.h>
    #define LL long long 
    #define db long double
    using namespace std;
    const int M = 1000050;
    int p[78498+50],cntp,pre[M];
    inline void sieve(int n){
    	static bool vis[M]; static int i,j; memset(vis,0,sizeof(vis));
    	for (i = 2; i <= n; ++i){
    		pre[i] = pre[i-1]; if (!vis[i]) p[++cntp] = i,++pre[i];
    		for (j = 1; i * p[j] <= n; ++j){ vis[i*p[j]] = 1; if (i % p[j] == 0) break; }
    	}
    }
    LL P;
    inline LL mul(LL x,LL y){
    	static LL ans; x %= P,y %= P,ans = x*y-P*(LL)((db)(x)*y/P);
    	if (ans < 0) ans += P; else if (ans >= P) ans -= P; return ans;
    }
    inline LL power(LL x,LL y){ static LL r; r = 1; while (y){ if (y&1) r = mul(r,x); x = mul(x,x),y>>=1; } return r; }
    inline LL calc(LL n,int p){ static LL r; r = 0; while (n >= p) n /= p,r += n; return r; }
    int id1[M],id2[M],cntid; LL n,m,num[M<<1],f[M<<1];
    inline int Id(LL x){ return x <= m ? id1[x] : id2[n/x]; }
    inline void Min25(){
    	LL l = 1,v; cntid = 0; m = min(n,(LL)(sqrt(n)) + 1);
    	if (n <= 1000000) return;
    	while (l <= n){
    		v = n/l; if (v <= m) id1[v] = ++cntid; else id2[n/v] = ++cntid;
    		num[cntid] = v,f[cntid] = v-1,l = n/v+1;
    	}
    	register int i,j;
    	for (i = 1; i <= cntp && (LL)p[i] * p[i] <= n; ++i)
    	for (v = (LL)p[i] * p[i],j = 1; j <= cntid && num[j] >= v; ++j)
    		f[j] -= f[Id(num[j]/p[i])]-(i-1);
    }
    inline LL ask(LL x){ return (x <= 1000000) ? pre[x] : f[Id(x)]; } 
    inline void solve(){
    	int i; LL ans = 1%P,l = 1,r,v,lst = 0,now; Min25();
    	for (i = 1; i <= cntp && (LL)p[i] * p[i] <= n; ++i) ans = mul(ans,1+calc(n,p[i])),++lst,l = p[i]+1;
    	while (l <= n) v = n/l,r = n/v,now = ask(r),ans = mul(ans,power(v+1,now-lst)),l = r+1,lst = now;
    	cout << ans << '
    ';
    }
    int main(){ sieve(1000000); int T; cin >> T; while (T--) cin >> n >> P,solve(); return 0; }
    
  • 相关阅读:
    强化学习的基本迭代方法
    基于文本描述的事务聚类
    学习强化学习之前需要掌握的3种技能
    其它 华硕 ASAU S4100U 系统安装 win10安装 重装系统 Invalid Partition Table 解决
    数据分析 一些基本的知识
    Python 取样式的内容 合并多个文件的样式 自定义样式
    电商 Python 生成补单公司需要的评论格式3
    SpringBlade 本地图片上传 生成缩略图
    SQL Server 字符串截取
    SpringBlade 本地图片上传
  • 原文地址:https://www.cnblogs.com/s-r-f/p/13581335.html
Copyright © 2011-2022 走看看