UR #5 怎样跑得更快

Posted weiyanpeng

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了UR #5 怎样跑得更快相关的知识,希望对你有一定的参考价值。

首先推出来这样一个东西:
\[ b_i=\sum\limits_j=1^n\gcd(i,j)^C-D\cdot i^D\cdot j^D\cdot x_j \]
现在令:
\[ \begin aligned b_i &= \frac b_i (i^D) \x_i &= x_i*i^D \end aligned \]
考虑\(C=1,D=0\)怎么做
\[ \begin aligned b_i &= \sum _j \sum _d|gcd(i,j) \phi (d) x_j \&=\sum_d|i \phi(d)\sum_j=1^\lfloor\fracnd\rfloorx_d*j \endaligned \]

\[ y_i = \sum _j=1^\lfloor\fracni\rfloorx_i \]

\[ g_i=\phi(i)*y_i \b_i = \sum _d|i g_d \g_i = \sum _d|i b_d\mu(d) \]
\(C=1,D=0\)就可以过了

现在考虑其他的情况,我们考虑构造一个函数F,使得:
\[ p_i=i^C-D=\sum _d|i f_d \]
同样反演:
\[ f_d = \sum_d|ip_d\mu(d) \]
把F和G求出来就有y了,然后还原成x输出就行。

无解的情况就是除的时候非0除0。

代码

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int mod=998244353;
inline int add(int a,int b)a+=b;return a>=mod?a-mod:a;
inline int sub(int a,int b)a-=b;return a<0?a+mod:a;
inline int mul(int a,int b)return 1ll*a*b%mod;
inline int qpow(int a,int b)int ret=1;for(;b;b>>=1,a=mul(a,a))if(b&1)ret=mul(ret,a);return ret;
inline int qinv(int x)return qpow(x,mod-2);
/* math */
const int N = 1e5+5;
int pcnt,prime[N],v[N],mu[N];
typedef vector<int> diric;
diric dirichlet_mul(diric a,diric b)
    diric c(a.size(),0);int n=a.size()-1;
    for(int i=1;i<=n;i++)for(int j=i;j<=n;j+=i)
        c[j]=add(c[j],mul(a[i],b[j/i]));
    return c;

diric transform(diric a)
    diric c(a.size(),0);int n=a.size()-1;
    for(int i=1;i<=n;i++)for(int j=i;j<=n;j+=i)
        c[i]=add(c[i],mul(a[j],mu[j/i]));
    return c;

int n,c,d,q;
diric x,y,g,MU,b,tot;

inline void sieve(int n)
    mu[1]=1;
    for(int i=2;i<=n;i++)
        if(!v[i])mu[i]=mod-1,prime[++pcnt]=i;
        for(int j=1;j<=pcnt&&1ll*i*prime[j]<=n;j++)
            int nxt=i*prime[j];v[nxt]=1;
            if(i%prime[j])mu[nxt]=mod-mu[i];
            else 
                mu[nxt]=0;
                break;
            
        
    
    MU.resize(n+1);
    for(int i=1;i<=n;i++)MU[i]=mu[i];


int main()

    cin >> n >> c >> d >> q;
    sieve(n);
    g.resize(n+1);
    for(int i=1;i<=n;i++)
        g[i]=((c-d>=0)? qpow(i,c-d) : qinv(qpow(i,d-c)));
    
    g=dirichlet_mul(g,MU);
    while(q--)
        bool EXIT=0;
        y.resize(n+1);
        b.resize(n+1);
        for(int i=1;i<=n;i++)scanf("%d",&b[i]), b[i]=mul(b[i],qinv(qpow(i,d)));
        tot=dirichlet_mul(b,MU);
        for(int i=1;i<=n;i++)
            y[i]=mul(tot[i],qinv(g[i]));
            if(tot[i]!=0 && g[i]==0)
                printf("-1\n");EXIT=1;break;
            
        
        if(EXIT)continue;
        x=transform(y);
        for(int i=1;i<=n;i++)printf("%d ",mul(x[i],qinv(qpow(i,d))));puts("");
    

以上是关于UR #5 怎样跑得更快的主要内容,如果未能解决你的问题,请参考以下文章

UOJ #62. UR #5怎样跑得更快

杂题选放

[UOJ62]怎样跑得更快

让Python跑得更快

10条SQL优化语句,让你的MySQL数据库跑得更快!

我可以让 Java 跑得更快吗? [关闭]