• 如约而至(walk)


    LCA大佬的做法:

    考虑暴力的高斯消元,我们优化它。

    $sumlimits_{j} gcd(i,j)^{c-d} i^d j^d x_j=b_i$

    $sumlimits_{j} gcd(i,j)^{c-d} y_j = frac{b_i}{i^d}$($y_j=j^d x_j$)

    那么高斯消元的矩阵的$(i,j)$位置的值就是$gcd(i,j)^{c-d}$,我们令$f(x)=x^{c-d}$

    我们对于高斯消元的矩阵,只需要保留记录$D[i][i]$位置上的值就可以了。

    然后当我们消到第$i$行时,有

    $egin{align*} D[i][j] &= 0 &(j mod i e 0) \ D[i][j] &= g(i) &(j mod i =0) end{align*}$

    证明:

    $g(i) =f(i)-sumlimits_{t|i,t<i}g(i)$

    令$d=gcd(i,j)$($j mod i e 0$),此时

    $D[i][j]=f(d)-sumlimits_{t|d} g(t) = f(d)-g(d)-sumlimits_{t|d,t<d}g(d)$

    因为$g(d) = f(d) - sumlimits_{t|d,t<d}g(d)$

    所以$D[i][j]=f(d)-f(d)=0$

    当$j mod i =0$时,$gcd(i,j)=i$,所以一开始的$D[i][j]$初始值一样,消的过程中减去的东西一样,所以最后的值也应该一样

    //Serene
    #include<algorithm>
    #include<iostream>
    #include<cstring>
    #include<cstdlib>
    #include<cstdio>
    #include<cmath>
    using namespace std;
    #define ll long long
    #define db double
    #define For(i,a,b) for(int i=(a);i<=(b);++i)
    #define Rep(i,a,b) for(int i=(a);i>=(b);--i)
    #define getchar gc
    const int maxn=1e6+7,maxt=1000+7;
    const ll mod=998244353;
    ll n,C,D,Td,b[maxn];
    
    inline char gc(){
        static char buf[100000],*p1=buf,*p2=buf;
        return p1==p2&&(p2=(p1=buf)+fread(buf,1,100000,stdin),p1==p2)?EOF:*p1++;
    }
    
    char cc;ll ff;
    template<typename T>void read(T& aa) {
    	aa=0;cc=getchar();ff=1;
    	while((cc<'0'||cc>'9')&&cc!='-') cc=getchar();
    	if(cc=='-') cc=getchar(),ff=-1;
    	while(cc>='0'&&cc<='9') aa=aa*10+cc-'0',cc=getchar();
    	aa*=ff;
    }
    
    ll qp(ll x,ll k) {
    	ll rs=1;
    	while(k) {
    		if(k&1) rs=rs*x%mod;
    		k>>=1; x=x*x%mod;
    	}
    	return rs;
    }
    
    ll finv(ll x) {return qp(x,mod-2);}
    
    ll qp1(ll x,ll k) {
    	if(k<0) return qp(x,k+(mod-1));
    	return qp(x,k);
    }
    
    ll ans[maxn],f[maxn];
    
    bool solve() {
    	For(i,1,n) b[i]=b[i]*finv(qp(i,D));
    	For(i,1,n) f[i]=qp1(i,C-D);
    	For(i,1,n) {
    		if(f[i]==0&&b[i]) return 0;
    		else if(f[i]==0) continue;
    		for(int j=i<<1;j<=n;j+=i) {
    			f[j]=(f[j]-f[i]+mod)%mod;
    			b[j]=(b[j]-b[i]+mod)%mod;
    		}
    		ans[i]=b[i]*finv(f[i])%mod;
    	}
    	Rep(i,n,1) {
    		for(int j=i<<1;j<=n;j+=i) 
    			ans[i]=(ans[i]-ans[j]+mod)%mod;
    	}
    	For(i,1,n) ans[i]=ans[i]*finv(qp(i,D))%mod;
    	return 1;
    }
    
    int main() {
    	freopen("walk.in","r",stdin);
    	freopen("walk.out","w",stdout);
    	read(n); read(C); read(D); read(Td);
    	while(Td--) {
    		For(i,1,n) read(b[i]);
    		if(!solve()) printf("-1");
    		else For(i,1,n) printf("%lld ",ans[i]);
    		printf("
    ");
    	}
    	return 0;
    }
    

      

  • 相关阅读:
    IOS:接口返回包含转义字符去掉转义字符
    properties和yml进行对比
    IDEA安装插件时搜索不到,一直在转圈刷新,无法安装
    VMware 15 虚拟机黑屏问题
    扩容根分区
    CentOS 6 各种启动文件损坏及修复
    RabbitMQ面试题
    FTP,SFTP服务器登录权限和根目录的设置
    Tee命令的几个使用实例
    ssh-copy-id 后无法免密登录
  • 原文地址:https://www.cnblogs.com/Serene-shixinyi/p/9199458.html
Copyright © 2020-2023  润新知