首页 > 其他 > 详细

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

时间:2019-06-05 18:58:05      阅读:87      评论:0      收藏:0      [点我收藏+]

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; 在不知道公式的情况下,我们可以用拉格朗日差值法求。

下面给出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;
}

这里的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;
}
View Code

 

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

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

(0)
(0)
   
举报
评论 一句话评论(0
关于我们 - 联系我们 - 留言反馈 - 联系我们:wmxa8@hotmail.com
© 2014 bubuko.com 版权所有
打开技术之扣,分享程序人生!