ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

「codeforces - 542D」Superhero's Job

2022-07-15 12:02:03  阅读:150  来源: 互联网

标签:md Superhero int LL Job 542D alpha sum dp


link。

容易发现,如果将 \(x\) 写作 \(\displaystyle \prod_{i = 1}^k p_i^{\alpha_i}\) 的形式,\(\displaystyle J(x) = 1+\sum p_i^{\alpha_i}+\sum\sum p_i^{\alpha_i}p_j^{\alpha_j}+\dots = \sum_{T \in 2^S} \sum_{i \in T} p_i^{\alpha_i}\),其中 \(S = \{1, \dots, k\}\)。写到这里可以发现 Joker function 是个 multiplicative function,所以 Joker function 又可以写作 \(\displaystyle J(x) = \prod_{i = 1}^k J(p_i^{\alpha_i}) = \prod_{i = 1}^k \left(p_i^{\alpha_i}+1\right)\)。

考虑 dp,设 \(f[i][j]\) 表示用前 \(i\) 个质数通过上述形式凑出 \(j\) 的方案数,转移很平凡,具体看代码。这个 dp 可以用数据结构来存。这个 dp 复杂度的保证在于 \(\displaystyle \max_{i \in [1, 10^{12}]} {\sigma_0(i)} = 6720\),这就叫人比较无语。至于判断一个数是否是 \(p^k+1\) 的形式,可以根号分治来做,记阈值为 \(T = 10^6\),对于 \(\leqslant T\) 的元素,可以线性筛出所有质数,标记所有质数的次幂,数量级粗略是 \(O(T\log T)\),完全跑不满;对于 \(> T\) 的元素,因为 \((T+1)^2 > 10^{12}\),所以只需要判断是否为质数即可,Miller Rabin 或者其他 nb 的判素数方法即可。

namespace Miller_Rabin{
	const int P[]={2,3,7,97,19260817};
	inline LL mul(LL a,LL b,const LL&md){
		LL tmp=a*b-(LL)((long double)a*b/md+.5)*md;
		return tmp+(tmp>>63&md);
	} 
	inline LL pow(LL a,LL b,const LL&md){
		LL ret=1;
		for(;b;b>>=1,a=mul(a,a,md))if(b&1)ret=mul(ret,a,md);
		return ret;
	}
	bool test(LL a,LL p){
		LL x=p-1;
		int d=0;
		while(!(x&1))++d,x>>=1;
		LL t=pow(a,x,p);
		while(d--){
			const LL ls=t;
			t=mul(t,t,p);
			if(t==1&&ls!=1&&ls!=p-1)return 0;
		}
		return t==1;
	}
	bool check(LL n){
		if(n<2)return 0;
		if(n==2||n==3||n==7||n==97||n==P[4])return 1;
		for(int i=0;i<5;++i)if(n%P[i]==0)return 0;
		for(int i=0;i<5;++i)
		if(!test(P[i]%n,n))return 0;
		return 1;
	}
}
using Miller_Rabin::check;
LL A;
bitset<1000100> tag;
int prm[1000100], cnt;
map<LL, int> mp; // a in it iff a = p^k
bastr<LL> offset[2000100];
void sieve(int n) {
    for (int i=2; i<=n; ++i) {
        if (!tag.test(i)) {
            prm[++cnt] = i;
        }
        for (int j=1; j<=cnt && i<=n/prm[j]; ++j) {
            tag.set(i*prm[j]);
            if (i%prm[j] == 0) {
                break;
            }
        }
    }
    for (int i=1; i<=cnt; ++i) {
        for (LL j=prm[i]; j<=1e12; j*=prm[i]) {
            mp[j] = i;
        }
    }
}
void executer() {
    cin >> A;
    map<LL, LL> dp[2];
    bastr<int> eff;
    for (LL i=1; i<=A/i; ++i) {
        if (A%i == 0) {
            if (mp.count(i-1)) {
                offset[mp[i-1]] += i;
                eff += mp[i-1];
            }
            if (i*i != A) {
                if (mp.count(A/i-1)) {
                    offset[mp[A/i-1]] += A/i;
                    eff += mp[A/i-1];
                }
                else if (check(A/i-1)) {
                    offset[++cnt] += A/i;
                    eff += cnt;
                }
            }
        }
    }
    sort(eff.begin(), eff.end());
    eff.erase(unique(eff.begin(), eff.end()), eff.end());
    dp[0][1] = 1;
    int cur = 1;
    for (auto u : eff) {
        dp[cur] = dp[cur^1];
        for (auto v : dp[cur^1]) {
            for (auto p : offset[u]) {
                if (A/p >= v.first && A%(v.first*p) == 0) {
                    dp[cur][v.first*p] += v.second;
                }
            }
        }
        cur ^= 1;
    }
    cout << dp[cs(eff)&1][A] << "\n";
}

标签:md,Superhero,int,LL,Job,542D,alpha,sum,dp
来源: https://www.cnblogs.com/orchid-any/p/16480863.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有