【UOJ#62】【UR #5】怎样跑得更快(莫比乌斯反演)

题面

UOJ

题解

众所周知,\(lcm(i,j)=\frac{ij}{gcd(i,j)}\),于是原式就变成了:

\[\sum_{j=1}^n gcd(i,j)^{c-d}i^dj^dx_j\equiv b_i
\]

于是我们就可以写成函数的形式:

\[\sum_{j=1}^n f(gcd(i,j))h(i)h(j)x_j\equiv b_i
\]

然后就开始枚举\(gcd\)。

\[\begin{aligned}
b_i&=\sum_{d=1}^n f(d)\sum_{j=1}^n [gcd(i,j)=d]h(i)h(j)x_j\\
&=\sum_{d=1}^n f(d) \sum_{j=1}^{n}[\frac{gcd(i,j)}{d}=1]h(i)h(j)x_j\\
&=\sum_{d|i} f(d) \sum_{d|j}h(i)h(j)\sum_{k|\frac{gcd(i,j)}{d}}\mu(k)x_j
\end{aligned}\]

条件等价于\(kd|gcd(i,j)\),令\(T=kd\)。

\[\begin{aligned}
b_i&=h(i)\sum_{d|i}f(d)\sum_{d|j}h(j)\sum_{T|gcd(i,j)}\mu(k)x_j\\
&=h(i)\sum_{T|i}\sum_{T|j}\sum_{d|T}f(d)x_j\mu(\frac{T}{d})h(j)\\
&=h(i)\sum_{T|i}\sum_{T|j}g(j)x_j\sum_{d|T}\mu(\frac{T}{d})f(d)
\end{aligned}\]

后半部分可以提前预处理出来,记做\(fr(T)\)。

继续往下就是:

\[\begin{aligned}
b_i&=h(i)\sum_{T|i}\sum_{T|j}h(j)x_j fr(T)\\
&=h(i)\sum_{T|i}fr(T)\sum_{T|j}h(j)x_j
\end{aligned}\]

考虑把后半部分的那个东西也给提前算出来,记做\(g(T)\)。

那么要求的就变成了\(\displaystyle b_i=h(i)\sum_{T|i}fr(T)g(T)\)

令\(gr(T)=fr(T)g(T)\),于是\(\displaystyle b_i=h(i)\sum_{T|i}gr(T)\)。

根据莫比乌斯反演可以得到:

\[\frac{b_i}{h(i)}=\sum_{T|i}gr(T)
\]

\[gr(i)=\sum_{T|i}\mu(\frac{i}{T})\frac{b_T}{h(T)}
\]

而\(gr\)是可以算出来的,\(fr\)也是可以算出来的,所以\(g\)也是可以算出来的。

而\(\displaystyle g(T)=\sum_{T|j}h(j)x_j\),那么通过莫比乌斯反演可以算出\(h(j)x_j\),直接除掉之后就能算出\(x_j\)了。

如果无解就是存在除法的时候出现了非零数除以\(0\)。

#include<iostream>
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<cmath>
#include<algorithm>
#include<vector>
using namespace std;
#define ll long long
#define MOD 998244353
#define MAX 100100
inline int read()
{
int x=0;bool t=false;char ch=getchar();
while((ch<'0'||ch>'9')&&ch!='-')ch=getchar();
if(ch=='-')t=true,ch=getchar();
while(ch<='9'&&ch>='0')x=x*10+ch-48,ch=getchar();
return t?-x:x;
}
int fpow(int a,int b){int s=1;while(b){if(b&1)s=1ll*s*a%MOD;a=1ll*a*a%MOD;b>>=1;}return s;}
int n,C,D,Q;
int pri[MAX],tot,mu[MAX];
bool zs[MAX];
void Sieve()
{
mu[1]=1;
for(int i=2;i<=n;++i)
{
if(!zs[i])pri[++tot]=i,mu[i]=-1;
for(int j=1;i*pri[j]<=n;++j)
{
zs[i*pri[j]]=true;
if(i%pri[j]==0)break;
mu[i*pri[j]]=-mu[i];
}
}
}
int b[MAX],gr[MAX],h[MAX],invh[MAX],f[MAX],g[MAX],fr[MAX],w[MAX],invfr[MAX];
int main()
{
n=read();C=read();D=read();Q=read();Sieve();
for(int i=1;i<=n;++i)h[i]=fpow(i,D),invh[i]=fpow(h[i],MOD-2);;
for(int i=1,p=(C-D+MOD-1)%(MOD-1);i<=n;++i)f[i]=fpow(i,p);
for(int i=1;i<=n;++i)
for(int j=i;j<=n;j+=i)
fr[j]=(0ll+fr[j]+mu[j/i]*f[i]+MOD)%MOD;
for(int i=1;i<=n;++i)invfr[i]=fpow(fr[i],MOD-2);
while(Q--)
{
for(int i=1;i<=n;++i)b[i]=read();
bool fl=true;
for(int i=1;i<=n;++i)w[i]=1ll*b[i]*invh[i]%MOD;
for(int i=1;i<=n;++i)if(b[i]&&!h[i])fl=false;
for(int i=1;i<=n;++i)gr[i]=0;
for(int i=1;i<=n;++i)
for(int j=i;j<=n;j+=i)
gr[j]=(0ll+gr[j]+mu[j/i]*w[i]+MOD)%MOD;
for(int i=1;i<=n;++i)g[i]=1ll*gr[i]*invfr[i]%MOD;
for(int i=1;i<=n;++i)if(gr[i]&&!invfr[i])fl=false;
for(int i=1;i<=n;++i)w[i]=0;
for(int i=1;i<=n;++i)
for(int j=i;j<=n;j+=i)
w[i]=(0ll+w[i]+mu[j/i]*g[j]+MOD)%MOD;
for(int i=1;i<=n;++i)if(w[i]&&!h[i])fl=false;
for(int i=1;i<=n;++i)w[i]=1ll*w[i]*invh[i]%MOD;
if(!fl){puts("-1");continue;}
for(int i=1;i<=n;++i)printf("%d ",w[i]);
puts("");
}
return 0;
}

【UOJ#62】【UR #5】怎样跑得更快(莫比乌斯反演)的更多相关文章

  1. UOJ 【UR #5】怎样跑得更快

    [UOJ#62]怎样跑得更快 题面 这个题让人有高斯消元的冲动,但肯定是不行的. 这个题算是莫比乌斯反演的一个非常巧妙的应用(不看题解不会做). 套路1: 因为\(b(i)\)能表达成一系列\(x(i ...

  2. 「UR#5」怎样跑得更快

    「UR#5」怎样跑得更快 膜这个您就会了 下面是复读机mangoyang 我们要求 \[ \sum_{j=1}^n \gcd(i,j)^{c-d} j^d x_j=\frac{b_i}{i^d} \] ...

  3. 让DB2跑得更快——DB2内部解析与性能优化

    让DB2跑得更快——DB2内部解析与性能优化 (DB2数据库领域的精彩强音,DB2技巧精髓的热心分享,资深数据库专家牛新庄.干毅民.成孜论.唐志刚联袂推荐!)  洪烨著 2013年10月出版 定价:7 ...

  4. 面试官:如何写出让 CPU 跑得更快的代码?

    前言 代码都是由 CPU 跑起来的,我们代码写的好与坏就决定了 CPU 的执行效率,特别是在编写计算密集型的程序,更要注重 CPU 的执行效率,否则将会大大影响系统性能. CPU 内部嵌入了 CPU ...

  5. UOJ#62. 【UR #5】怎样跑得更快 数论 莫比乌斯反演

    原文链接https://www.cnblogs.com/zhouzhendong/p/UOJ62.html 题解 太久没更博客了,该拯救我的博客了. $$\sum_{1\leq j \leq n} \ ...

  6. [翻译] 5点建议,让iOS程序跑得更快

      [文章原地址]http://mobile.tutsplus.com/tutorials/iphone/ios-quick-tip-5-tips-to-increase-app-performanc ...

  7. 让你的 Node.js 应用跑得更快的 10 个技巧(转)

    Node.js 受益于它的事件驱动和异步的特征,已经很快了.但是,在现代网络中只是快是不行的.如果你打算用 Node.js 开发你的下一个Web 应用的话,那么你就应该无所不用其极,让你的应用更快,异 ...

  8. 安装好Windows 8后必做的几件事情,让你的Win8跑的更快更流畅。

    1.关闭家庭组,因为这功能会导致硬盘和CPU处于高负荷状态. 关闭方法:Win+C-设置-更改电脑设置-家庭组-离开 如果用不到家庭组可以直接把家庭组服务也给关闭了:控制面板-管理工具-服务-Home ...

  9. 让你的 Node.js 应用跑得更快的 10 个技巧

    Node.js 受益于它的事件驱动和异步的特征,已经很快了.但是,在现代网络中只是快是不行的.如果你打算用 Node.js 开发你的下一个Web 应用的话,那么你就应该无所不用其极,让你的应用更快,异 ...

随机推荐

  1. yolov3和ssd的区别

    版权声明:本文为博主原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接和本声明. 本文链接:https://blog.csdn.net/BlowfishKing/article/d ...

  2. Python中字符的编码与解码

    1 文本和字节序列 我们都知道字符串,就是由一些字符组成的序列构成串,那么字符又是什么呢?计算机只能识别二进制的东西,那么计算机又为什么会显示我们的汉字,或者是某个字母呢? 由于最早发明使用计算机是美 ...

  3. MySQL GROUP BY 的问题

    拿 employee 示例数据库为例,当进行如下操作时会报错. mysql> SELECT * FROM employees GROUP BY gender; ERROR 1055 (42000 ...

  4. SpringBoot捕获AccessDeniedException

    https://www.jianshu.com/p/bb14cca5ab3d 自定义AccessDeniedHandler /** * @Author: jialing xu * @Descripti ...

  5. Spring Boot 中如何定制 Banner

    本人免费整理了Java高级资料,涵盖了Java.Redis.MongoDB.MySQL.Zookeeper.Spring Cloud.Dubbo高并发分布式等教程,一共30G,需要自己领取.传送门:h ...

  6. Python--方法/技巧在哪用的典型例子

    就我个人在学习Python的过程中,经常会出现学习了新方法后,如果隔上几天不用,就忘了的情况,或者刚学习的更好的方法没有得到应用,还是沿用已有的方法,这样很不利于学习和掌握新姿势,从而拉长学习时间,增 ...

  7. 程序卡在 while(SPI_I2S_GetFlagStatus(W5500_SPI, SPI_I2S_FLAG_TXE) == RESET) 处

    stm32 SPI1,发现程序卡在 while(SPI_I2S_GetFlagStatus(W5500_SPI, SPI_I2S_FLAG_TXE) == RESET); 解决方式: 1.检查RCC时 ...

  8. 测试文档(final)

    1 引言 1.1编写目的 编写本测试计划的目的是: (1)     为整个测试阶段的管理工作和技术工作提供指南同时确定测试的内容和范围,为评价系统提供依据: (2)     此外还帮助安排测试活动,说 ...

  9. MySQL 部署分布式架构 MyCAT (五)

    分片(水平拆分) 4.全局表 业务使用场景: 如果你的业务中有些数据类似于数据字典,比如配置文件的配置, 常用业务的配置或者数据量不大很少变动的表,这些表往往不是特别大, 而且大部分的业务场景都会用到 ...

  10. viscode 使用 格式的配置

    viscode 现在也越来越适用于 python 开发使用的 IDEA ,慢慢不逊色于  pycharm .下面是关于使用的 格式[字体颜色,背景之类的配置] 1. 2. 如果是设置的 中文显示,在界 ...