【UOJ#62】怎样跑得更快

题面

这个题让人有高斯消元的冲动,但肯定是不行的。

这个题算是莫比乌斯反演的一个非常巧妙的应用(不看题解不会做)。

套路1:

因为\(b(i)\)能表达成一系列\(x(i)\)的和,所以我们尝试通过反演将\(x(i)\)表达成一系列\(b(i)\)的和的形式,那么就可以解出来了。

然后一个简单的化简:\(gcd(i,j)^c\cdot lcm(i,j)^d=i^d\cdot j^d\cdot gcd(i,j)c-d\)。

\[\displaystyle b_i=\sum_{j=1}^ni^dj^dgcd(i,j)^{c-d}x_j\\
\frac{b_i}{i^d}=\sum_{j=1}^ngcd(i,j)^{c-d}j^dx_j
\]

套路2:

看到gcd非常不爽,考虑干掉它。

我们设\(f(i)=i^{c-d}\),再构造函数\(fr(i)\),使得\(f(n)=\sum_{d|n}fr(d)\)。\(d|gcd(i,j)\Rightarrow d|i,d|j\)。

由莫比乌斯反演可以得到\(fr(n)=\sum_{d|n}\mu(d)f(\frac{n}{d})\)

所以

\[\displaystyle\frac{b_i}{i^d}=\sum_{j=1}^n\sum_{d|i,d|j}fr(d) j^dx_j\\
\]

然后我们要将右边的式子交换求和符号(因为我们要得到套路1的形式)。

\[\displaystyle\frac{b_i}{i^d}=\sum_{j=1}^n\sum_{d|i,d|j}fr(d) j^dx_j\\
=\sum_{d|i}fr(d)\sum_{d|j}j^dx_j\\
\]

套路3:

我们设\(Z_d=\sum_{d|j}j^dx_j\)。

于是\(\displaystyle\frac{b_i}{i^d}=\sum_{d|i}fr(d)Z_d\),然后我们呢将\(fr(d)\)解出来了过后就可以将\(Z_d\)解出来。

又是莫比乌斯反演

\[\displaystyle Z_d=\sum_{d|j}j^dx_j\\
j^dx_j=\sum_{j|d}\mu(\frac{d}{j})Z_j
\]

三个反演,就将这道好题(毒瘤题)解决了。

总结:

反演在两个函数直接构建了转换的桥梁,遇到难以求解的函数时,通常将其反演成一个好求的函数再反演回来。

代码:

#include<bits/stdc++.h>
#define ll long long
#define N 100005 using namespace std;
inline int Get() {int x=0,f=1;char ch=getchar();while(ch<'0'||ch>'9') {if(ch=='-') f=-1;ch=getchar();}while('0'<=ch&&ch<='9') {x=(x<<1)+(x<<3)+ch-'0';ch=getchar();}return x*f;} int n,c,d,q;
ll f[N],b[N],g[N],h[N];
ll fr[N],z[N];
ll s[N],ans[N];
const ll mod=998244353;
ll ksm(ll t,ll x) {
ll ans=1;
for(;x;x>>=1,t=t*t%mod)
if(x&1) ans=ans*t%mod;
return ans;
}
bool vis[N];
int pri[N],mu[N]; void pre(int n) {
mu[1]=1;
for(int i=2;i<=n;i++) {
if(!vis[i]) {
pri[++pri[0]]=i;
mu[i]=-1;
}
for(int j=1;j<=pri[0]&&1ll*i*pri[j]<=n;j++) {
vis[i*pri[j]]=1;
if(i%pri[j]==0) {
break;
}
mu[i*pri[j]]=-mu[i];
}
}
} ll tem[N];
void solve() {
for(int i=1;i<=n;i++) {
if(fr[i]==0&&s[i]) {cout<<-1<<"\n";return ;}
z[i]=s[i]*ksm(fr[i],mod-2)%mod;
}
for(int i=1;i<=n;i++) tem[i]=0;
for(int i=1;i<=n;i++) {
for(int j=i;j<=n;j+=i) {
(tem[i]+=mu[j/i]*z[j]+mod)%=mod;
}
}
for(int i=1;i<=n;i++) {
if(!h[i]&&tem[i]) {cout<<-1<<"\n";return ;}
ans[i]=tem[i]*ksm(h[i],mod-2)%mod;
}
for(int i=1;i<=n;i++) cout<<ans[i]<<" ";cout<<"\n";
} int main() {
n=Get(),c=Get(),d=Get(),q=Get();
pre(n);
int t=c-d;
t=(t%(mod-1)+mod-1)%(mod-1);
for(int i=0;i<=n;i++) f[i]=ksm(i,t);
for(int i=1;i<=n;i++) {
h[i]=g[i]=ksm(i,d);
}
for(int i=1;i<=n;i++)
for(int j=i;j<=n;j+=i)
(fr[j]+=mu[j/i]*f[i]+mod)%=mod;
while(q--) {
for(int i=1;i<=n;i++) {
s[i]=0;
b[i]=Get();
b[i]=b[i]*ksm(g[i],mod-2)%mod;
}
for(int i=1;i<=n;i++)
for(int j=i;j<=n;j+=i)
(s[j]+=mu[j/i]*b[i]+mod)%=mod;
solve();
}
return 0;
}

UOJ 【UR #5】怎样跑得更快的更多相关文章

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

    [UOJ#62][UR #5]怎样跑得更快(莫比乌斯反演) 题面 UOJ 题解 众所周知,\(lcm(i,j)=\frac{ij}{gcd(i,j)}\),于是原式就变成了: \[\sum_{j=1} ...

  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. [翻译] 5点建议,让iOS程序跑得更快

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

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

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

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

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

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

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

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

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

随机推荐

  1. 微信小程序https配置

    先简单说下什么是https,https与http区别 ,以及https的原理 什么是https 在说HTTPS之前先说说什么是HTTP,HTTP就是我们平时浏览网页时候使用的一种协议.HTTP协议传输 ...

  2. K均值聚类

    聚类(cluster)与分类的不同之处在于, 分类算法训练过程中样本所属的分类是已知的属监督学习. 而聚类算法不需要带有分类的训练数据,而是根据样本特征的相似性将其分为几类,又称为无监督分类. K均值 ...

  3. 分布式版本控制系统GIT的使用

    一.什么是Git Git是一个分布式版本控制系统,Git 和其他版本控制系统的主要差别在于,Git 只关心文件数据的整体是否发生变化,而大多数其他系统则只关心文件内容的具体差异(如CVS.Subver ...

  4. Liunx-常用命令杂烩(5)

    快捷键 ctrl+alt        显示鼠标 ctrl+alt+tab+F1~F6 :进入字符终端界面tty1~tty6,例如 ctrl+alt+tab+F7 :退出字符终端界面 简单命令相关 w ...

  5. JPA与EJB3的关系

    JPA是基于Java持久化的解决方案,主要是为了解决ORM框架的差异,它的出现在某种程度上能够解决目前ORM框架之间不能够兼容的问题,对开发人员来说,能够更好的在JPA规范下进行系统开发. JPA全称 ...

  6. java - 并发编程易错实例

    生产者消费者问题 https://juejin.im/post/5aeec675f265da0b7c072c56 notify()发生在wait()之前会怎么样?怎么处理? wati()等待条件的变化 ...

  7. Python 最佳实践指南 2018 学习笔记

    基础信息 版本 Python 2.7 Python 3.x Python2.7 版本在 2020 年后不再提供支持,建议新手使用 3.x 版本进行学习 实现 CPython:Python的标准实现: ...

  8. Python 练习: 简单角色游戏程序

    要求: 1.创建三个游戏人物,分别是: 苍井井,女,18,初始战斗力1000 东尼木木,男,20,初始战斗力1800 波多多,女,19,初始战斗力2500 2.游戏场景,分别: 草丛战斗,消耗200战 ...

  9. Spider-one

    1. 爬虫是如何采集网页数据的: 网页的三大特征: -1. 每个网页都有自己的 URL(统一资源定位符)地址来进行网络定位. -2. 每个网页都使用 HTML(超文本标记语言)来描述页面信息. -3. ...

  10. SFTP 文件配置

    sftp_config_file SFTP配置文件(Sublime Text 3 .VS Code) VS Code 的版本 { "host": "120.01.01.1 ...