HDU 6868 Absolute Math

Here

就放个式子和代码吧

如果有人推出了这个式子求告知

可以参考一下这个解析

该份讲解中的 g ( T ) g(T) g(T)函数就相当于我这个式子 a n s = f ( n ) ∑ g ∣ n μ ( g ) ∑ i = 1 ⌊ m g ⌋ f ( i g ) f ( g ) ans=f(n)\sum\limits_{g|n}^{}μ(g)\sum\limits_{i=1}^{\lfloor\frac{m}{g}\rfloor}\frac{f(ig)}{f(g)} ans=f(n)gnμ(g)i=1gmf(g)f(ig)中的 μ ( g ) f ( g ) \frac{μ(g)}{f(g)} f(g)μ(g)

所以这个式子 a n s = f ( n ) ∑ g ∣ n μ ( g ) ∑ i = 1 ⌊ m g ⌋ f ( i g ) f ( g ) ans=f(n)\sum\limits_{g|n}^{}μ(g)\sum\limits_{i=1}^{\lfloor\frac{m}{g}\rfloor}\frac{f(ig)}{f(g)} ans=f(n)gnμ(g)i=1gmf(g)f(ig)

f ( g ) f(g) f(g)提出来就变成了 a n s = f ( n ) ∑ g ∣ n μ ( g ) f ( g ) ∑ i = 1 ⌊ m g ⌋ f ( i g ) ans=f(n)\sum\limits_{g|n}^{}\frac{μ(g)}{f(g)}\sum\limits_{i=1}^{\lfloor\frac{m}{g}\rfloor}{f(ig)} ans=f(n)gnf(g)μ(g)i=1gmf(ig)

由于 ∑ i = 1 ⌊ m g ⌋ f ( i g ) \sum\limits_{i=1}^{\lfloor\frac{m}{g}\rfloor}{f(ig)} i=1gmf(ig)无法进行预处理,所以可以把 T T T组样例当作整体一起来做。

由于每个 n n n最多也就10个左右的质因子,所以整体最多有 T ∗ 10 T*10 T10个质因子,把每个质因子对应第几个case,还有m的值存下来,然后对每个质因子求 ∑ i = 1 ⌊ m g ⌋ f ( i g ) \sum\limits_{i=1}^{\lfloor\frac{m}{g}\rfloor}{f(ig)} i=1gmf(ig)的值,当求到一定 m m m的时候就可以把贡献加到相应的case里面去。

这样整体的复杂度就变成了 O ( T ∗ 10 ∗ l o g m ) O(T*10*log m) O(T10logm),由于我还有另外预处理的一些复杂度,然后杭电平时的评测机好像不太行,赛后就TLE了。

Code 赛时 2343MS/5000MS 赛后 TLE

/****************************
* Author : 水娃             *
* Date : 2020-08-18-11.35.42*
****************************/
#pragma GCC optimize(3,"Ofast","inline")
#include
using namespace std;
#define mst(a,b) memset(a,b,sizeof(a))
#define ll long long
#define debug(a) cout<<#a<<" is "<
#define ull unsigned long long
#define fi first
#define se second
typedef pair<int,int>pii;
typedef pair<ll,int>pli;
typedef pair<int,ll>pil;
typedef pair<ll,ll>pll;
const ll mo=(ll)1e9+7;
ll gcd(ll a,ll b){return b==0?a:gcd(b,a%b);}
const int MAXN=1e7+100;
int now;
int mu[MAXN];
int pri[MAXN>>1];
bool vis[MAXN];
int val[MAXN];
void pre()
{
    now=0;
    mu[1]=1;
    for(int i=2;i<MAXN;i++)
    {
        if(!vis[i])
        {
            pri[++now]=i;
            mu[i]=-1;
        }
        for(int j=1;j<=now&&i*pri[j]<MAXN;j++)
        {
            vis[i*pri[j]]=1;
            if(i%pri[j])
            {
                mu[i*pri[j]]=-mu[i];
            }
            else
            {
                mu[i*pri[j]]=0;
                break;
            }
        }
    }
    for(int i=1;i<MAXN;i++)
    {
        for(int j=1;j*i<MAXN;j++)
        {
            val[i*j]+=abs(mu[i]);
        }
    }
}
unordered_map<int,vector<pii> >mp;
ll ans[11000],tmpans[11000];
void work()
{
    int t,n,m,top;
    cin>>t;
    for(int i=1;i<=t;i++)
    {
        cin>>n>>m;
        ans[i]=val[n];
        top=sqrt(n);
        for(int j=1;j<=top;j++)
        {
            if(n%j==0)
            {
                mp[j].push_back({m,i});
                if(n/j!=j)mp[n/j].push_back({m,i});
            }
        }
    }
    auto p=mp.begin();
    while(p!=mp.end())
    {
        sort(p->se.begin(),p->se.end());
        p++;
    }
    p=mp.begin();
    int g,curt;
    ll curans=0;
    vector<pii > cur;/// m t
    while(p!=mp.end())
    {
        g=p->fi;
        cur=p->se;
        curt=1;
        curans=0;
        p++;
        for(int i=0;i<cur.size();i++)
        {
            for(;curt*g<=cur[i].fi;curt++)
            {
                curans=(curans+val[curt*g]/val[g])%mo;
            }
            tmpans[cur[i].se]=((tmpans[cur[i].se]+mu[g]*curans)%mo+mo)%mo;
        }
    }
    for(int i=1;i<=t;i++)
    {
        cout<<(tmpans[i]*ans[i])%mo<<"\n";
    }
}
int main()
{
    ios::sync_with_stdio(0);
    cin.tie(0);cout.tie(0);
    pre();
        work();
    return 0;
}

UPD:CF是能过的

HDU 6868 Absolute Math_第1张图片

后面经过优化和测试,在HDU大概要7269MS左右,在CF能优化到3462MS,估计是比赛的时候的评测比较强吧

你可能感兴趣的:(数学)