HDU - 4059: The Boss on Mars (容斥 拉格朗日 优化)

pro: T次询问,每次给出N(N<1e8),求所有Σi^4 (i<=N,且gcd(i,N)==1) ;

sol:  因为N比较小,我们可以求出素因子,然后容斥。  主要问题就是求1到P的4次幂和。  我们知道K次幂和是一个K+1次多项式。

这里有公式Pre=P*(P+1)*(2P+1)*(3P^2+3P-1)/30; 在不知道公式的情况下,我们可以用拉格朗日差值法求。

1,下面给出DFS容斥的代码 。

#include<bits/stdc++.h>
#define ll long long
#define rep(i,a,b) for(int i=a;i<=b;i++)
using namespace std;
const int maxn=2000010;
const ll Mod=1e9+7;
int p[maxn],tot,N,T,ans,Rev=233333335;
void init()
{
    ll tN=N; tot=0; ans=0;
    for(int i=2;i<=tN/i;i++){
        if(tN%i==0){
            p[++tot]=i;
            while(tN%i==0) tN/=i;
        }
    }
    if(tN>1) p[++tot]=tN;
}
int get(ll y)
{
    ll res=y*(y+1)%Mod;
    res=(y*2+1)%Mod*res%Mod;
    res=(y*y%Mod*3%Mod+(y*3-1)%Mod)*res%Mod;
    res=res*Rev%Mod;
    return res;
    return 1LL*y*(y+1)%Mod*(y*2%Mod+1)%Mod*((3LL*y%Mod*y%Mod+y*3%Mod-1+Mod)%Mod)%Mod*Rev%Mod;
}
void dfs(int pos,int opt,ll sum)
{
    if(pos==tot+1){
        ll t=1LL*sum*sum%Mod*sum%Mod*sum%Mod;
        ll x=get(N/sum);
        x=x*t%Mod;
        if(opt==1) ans=(ans+x)%Mod;
        else ans=((ans-x)%Mod+Mod)%Mod;
        return ;
    }
    dfs(pos+1,opt,sum);
    dfs(pos+1,-opt,sum*p[pos]);
}
int main()
{
    scanf("%d",&T);
    while(T--){
        scanf("%d",&N);
        init();
        dfs(1,1,1LL);
        printf("%d\n",ans);
    }
    return 0;
}

2,这里的DFS还可以小小的优化一下, 想象一下,DFS的过程是遍历一颗二叉树,那么它遍历了所有的节点, 而且遍历的过程是老老实实一步步走下去的,所以还可以优化一下。   假设不操作则加入左儿子,有操作进入右儿子。 由于每次我遍历到叶子节点才进行计算, 所以很多时候,我向左走其实进行了一些没有价值的访问,会浪费一些时间。

而我现在可以在非叶子节点就进行计算,非叶子节点代表的是一直左走代表的叶子(即用节点代表对应的叶子,减少了不必要的访问)。  这样的话,不会存在浪费。 (虽然在此题中未体现出优劣性,但是去年深圳热身赛有一道搜索题就需要这样才能过。

#include<bits/stdc++.h>
#define rep(i,a,b) for(int i=a;i<=b;i++)
using namespace std;
const int maxn=2000010;
const int Mod=1e9+7;
int p[maxn],tot,N,T,ans,Rev=233333335;
void init()
{
    int tN=N; tot=0; ans=0;
    for(int i=2;i*i<=tN;i++){
        if(tN%i==0){
            p[++tot]=i;
            while(tN%i==0) tN/=i;
        }
    }
    if(tN>1) p[++tot]=tN;
}
void dfs(int pos,int opt,int sum) //稍微优化后的DFS
{
    int t=1LL*sum*sum%Mod*sum%Mod*sum%Mod;
    int y=N/sum;
    int x=1LL*y*(y+1)%Mod*(y*2+1)%Mod*(1LL*y*y*3%Mod+y*3-1)%Mod*Rev%Mod;
    if(opt==1) (ans+=1LL*x*t%Mod)%=Mod;
    else ((ans-=1LL*x*t%Mod)+=Mod)%=Mod;
    for(int i=pos+1;i<=tot;i++){
        dfs(i,-opt,sum*p[i]);
    }
}
int main()
{
    scanf("%d",&T);
    while(T--){
        scanf("%d",&N);
        init();
        dfs(0,1,1);
        printf("%d\n",ans);
    }
    return 0;
}

3,以及把公式改为拉格朗日差值来求的代码,4次多项式,前者和为5次多项式,可以通过求前6项来求:(当然这里的拉格朗日还可以优化为O(N),我懒得改了

#include<bits/stdc++.h>
#include<bits/stdc++.h>
#define rep(i,a,b) for(int i=a;i<=b;i++)
using namespace std;
const int maxn=2000010;
const int Mod=1e9+7;
int X[maxn]={0,1,2,3,4,5,6},Y[maxn]={0,1,17,98,354,979,2275};
int p[maxn],tot,N,T,ans,Rev=233333335;
int qpow(int a,int x)
{
    int res=1; while(x){
        if(x&1) res=1LL*res*a%Mod;
        x>>=1; a=1LL*a*a%Mod;
    }
    return res;
}
int Lange(int K)
{
    int res=0;
    rep(i,1,6) {
        int tmp=Y[i];
        rep(j,1,6) {
            if(j==i) continue;
            tmp=1LL*tmp*(K-X[j])%Mod*qpow(X[i]-X[j],Mod-2)%Mod;
            tmp=(tmp+Mod)%Mod;
        }
        (res+=tmp)%=Mod;
    }
    return res;
}
void init()
{
    int tN=N; tot=0; ans=0;
    for(int i=2;i*i<=tN;i++){
        if(tN%i==0){
            p[++tot]=i;
            while(tN%i==0) tN/=i;
        }
    }
    if(tN>1) p[++tot]=tN;
}
void dfs(int pos,int opt,int sum) //稍微优化后的DFS
{
    int t=1LL*sum*sum%Mod*sum%Mod*sum%Mod;
    int y=N/sum;
    int x=Lange(y);
    if(opt==1) (ans+=1LL*x*t%Mod)%=Mod;
    else ((ans-=1LL*x*t%Mod)+=Mod)%=Mod;
    for(int i=pos+1;i<=tot;i++){
        dfs(i,-opt,sum*p[i]);
    }
}
int main()
{
    scanf("%d",&T);
    while(T--){
        scanf("%d",&N);
        init();
        dfs(0,1,1);
        printf("%d\n",ans);
    }
    return 0;
}

原文地址:https://www.cnblogs.com/hua-dong/p/10981246.html

时间: 2024-10-08 19:29:06

HDU - 4059: The Boss on Mars (容斥 拉格朗日 优化)的相关文章

hdu 4059 The Boss on Mars(容斥)

http://acm.hdu.edu.cn/showproblem.php?pid=4059 定义S = 1^4 + 2^4 + 3^4+.....+n^4,现在减去与n互质的数的4次方,问共减少了多少. 容斥原理,可以先把与n不互质的数的4次方求出来.那就先对n进行质因子分解,对质因子的组合运用容斥原理,质因子个数为奇数就加,偶数就减.其实与求[1,n]内与n互质的数的个数类似,该题重点是计算,防止乘法溢出. 对于求解1^4 + 2^4 + 3^4+.....+n^4,可以先类比1^2+2^2

数论 + 容斥 - HDU 4059 The Boss on Mars

The Boss on Mars Problem's Link Mean: 给定一个整数n,求1~n中所有与n互质的数的四次方的和.(1<=n<=1e8) analyse: 看似简单,倘若自己手动推公式的话,还是需要一定的数学基础. 总的思路:先求出sum1=(1^4)+(2^4)+...(n^4),再求出sum2=(1~n中与n不互质的数的四次方的和),answer=sum1-sum2. 如何求sum1呢? 有两种方法: 1.数列差分.由于A={Sn}={a1^4+a2^4+...an^4}

hdu 4059 The Boss on Mars

The Boss on Mars Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) Total Submission(s): 1934    Accepted Submission(s): 580 Problem Description On Mars, there is a huge company called ACM (A huge Company on Mars), an

HDU 4059 The Boss on Mars(数论)

题目大意:给你一个n(10^8)以内,让你求出1-n中与n互质的数x^4的和. 解题思路:先把n进行分解质因数,然后容斥求出所有与n不互质的数x^4的和,然后做减法用总的减去不互质的就是互质的. 注意:1^4+2^4+--+n^4 = n(n+1)(2n+1)(3n^2+3n-1)/30. The Boss on Mars Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) Tot

HDU 4059 The Boss on Mars ( 容斥原理)

题目链接: http://acm.hdu.edu.cn/showproblem.php?pid=4059 题意: 给定一个数n求小于n的与n互斥的数的四次方的和. 分析: 我们可以求出从1~n的所有数的四次方的和sum1,然后容斥求出1~n所有与n不互斥的数的四次方的和sum2: ans =sum1 - sum2; 设f(n)表示从1~n的所有数的四次方的和 f(n)=1/30*n*(n+1)(2n+1)(3n^2+3n-1); 推倒如下: (n+1)^5-n^5=5n^4+10n^3+10n^

hdu 4059 The Boss on Mars(纳入和排除)

http://acm.hdu.edu.cn/showproblem.php?pid=4059 定义S = 1^4 + 2^4 + 3^4+.....+n^4.如今减去与n互质的数的4次方.问共降低了多少. 容斥原理.能够先把与n不互质的数的4次方求出来.那就先对n进行质因子分解,对质因子的组合运用容斥原理.质因子个数为奇数就加,偶数就减.事实上与求[1,n]内与n互质的数的个数类似,该题重点是计算,防止乘法溢出. 对于求解1^4 + 2^4 + 3^4+.....+n^4,能够先类比1^2+2^

HDU 4059 The Boss on Mars-矩阵+容斥

错了29遍,终成正果..... 根据题意,很容易的可以想到容斥. 然后的问题就是如何求 sum(n)=1^4+2^4+3^4+....+n^4; 有三种道路: 很显然:1^4+2^4+3^4+....+n^4=(n^5)/5+(n^4)/2+(n^3)/3-n/30: 则1,用java的大数去敲这个的代码. 2,用c++敲,但是用到分数取模,求逆元. 3,用c++敲,但是不用这个公式,用矩阵去构造sum(n). 我用的是第三种.但是第三种有的缺陷,就是时间复杂度有点高. 接下来的问题就是如何优化

hdu 6059 Kanade&#39;s trio(trie+容斥)

题目链接:hdu 6059 Kanade's trio 题意: 给你n个数,让你找有多少个(i,j,k),使得i<j<k满足a[i]^a[j]<a[j]^a[k]. 题解: 首先考虑a[i]和a[k],将他们都转换成二进制,对于a[i]和a[k],我们用Bi[p]表示二进制下的a[i]的第p位.考虑a[i]和a[k]二进制不同的最高位,这里假设为p,如果Bi[p]=0,Bk[p]=1,那么Bj[p]要为0,才能使得a[i]^a[j]<a[j]^a[k].(因为p前面的位相同,只有亦

4559[JLoi2016]成绩比较 容斥+拉格朗日插值法

4559: [JLoi2016]成绩比较 Time Limit: 20 Sec  Memory Limit: 256 MBSubmit: 261  Solved: 165[Submit][Status][Discuss] Description G系共有n位同学,M门必修课.这N位同学的编号为0到N-1的整数,其中B神的编号为0号.这M门必修课编号为0到M- 1的整数.一位同学在必修课上可以获得的分数是1到Ui中的一个整数.如果在每门课上A获得的成绩均小于等于B获 得的成绩,则称A被B碾压.在B