zoukankan      html  css  js  c++  java
  • UR #5 怎样跑得更快

    首先推出来这样一个东西:

    [b_i=sumlimits_{j=1}^ngcd(i,j)^{C-D}cdot i^Dcdot j^Dcdot x_j ]

    现在令:

    [egin {aligned} b_i &= frac {b_i} {(i^D)} \ x_i &= x_i*i^D end {aligned} ]

    考虑(C=1,D=0)怎么做

    [egin {aligned} b_i &= sum _j sum _{d|gcd(i,j)} phi (d) x_j \ &=sum_{d|i} phi(d)sum_{j=1}^{lfloorfrac{n}{d} floor}x_{d*j} end{aligned} ]

    [y_i = sum _{j=1}^{lfloorfrac{n}{i} floor}x_i ]

    [g_i=phi(i)*y_i \ b_i = sum _{d|i} g_d \ g_i = sum _{d|i} b_dmu(i/d) ]

    (C=1,D=0)就可以过了

    现在考虑其他的情况,我们考虑构造一个函数F,使得:

    [p_i=i^{C-D}=sum _{d|i} f_d ]

    同样反演:

    [f_d = sum_{d|i}p_dmu(i/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
    ");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("");
    	}
    }
    
  • 相关阅读:
    前端提示“页面正在载入”的功能实现
    JSON那些事
    如何让nodejs同步操作
    nodejs的一些局限
    《javascript高级程序设计》读书笔记——作用域
    svn教程
    从雷军谈小米中的一些思考
    云Vps安全设置
    不同服务器数据库之间的数据操作
    C#语言的Excel文件导入导出
  • 原文地址:https://www.cnblogs.com/weiyanpeng/p/11020502.html
Copyright © 2011-2022 走看看