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

题目分析

显然不可能高斯消元。

考虑反演。

\(b_i=\sum\limits_{j=1}^n\gcd(i,j)^C\cdot \text{lcm}(i,j)^D\cdot x_j\)

\(b_i=\sum\limits_{j=1}^n\gcd(i,j)^C\cdot \frac{i^D\cdot j^D}{\gcd(i,j)^D}\cdot x_j\)

\(b_i=\sum\limits_{j=1}^n\gcd(i,j)^{C-D}\cdot i^D\cdot j^D\cdot x_j\)

实际上形如\(b_i=\sum\limits_{j=1}^nf(\gcd(i,j))\cdot g(i)\cdot h(j)\cdot x_j\)都可以做。

我们按照套路化一下式子。

\(b_i=\sum\limits_{d|i}\sum\limits_{d|j}[\gcd(i,j)=d]\cdot f(d)\cdot g(i)\cdot h(j)\cdot x_j\)

将\([\gcd(i,j)=d]\)换成\(\sum\limits_{k|\frac{\gcd(i,j)}{d}}\mu(k)\)。

\(b_i=\sum\limits_{d|i}\sum\limits_{d|j}\sum\limits_{k|\frac{\gcd(i,j)}{d}}\mu(k)\cdot f(d)\cdot g(i)\cdot h(j)\cdot x_j\)

\(b_i=\sum\limits_{d|i}\sum\limits_{d|j}\sum\limits_{k \cdot d|\gcd(i,j)}\mu(k)\cdot f(d)\cdot g(i)\cdot h(j)\cdot x_j\)

\(b_i=\sum\limits_{T|i}\sum\limits_{T|j}\sum\limits_{d|T}\mu(\frac{T}{d})\cdot f(d)\cdot g(i)\cdot h(j)\cdot x_j\)

\(\frac{b_i}{g(i)}=\sum\limits_{T|i}\sum\limits_{T|j}\sum\limits_{d|T}\mu(\frac{T}{d})\cdot f(d)\cdot h(j)\cdot x_j\)

设\(fr(T)=\sum\limits_{d|T}\mu(\frac{T}{d})\cdot f(d)\)。

\(\frac{b_i}{g(i)}=\sum\limits_{T|i}\sum\limits_{T|j}fr(T)\cdot h(j)\cdot x_j\)

\(\frac{b_i}{g(i)}=\sum\limits_{T|i}fr(T)\sum\limits_{T|j}h(j)\cdot x_j\)

设\(q(T)=\sum\limits_{T|j}h(j)\cdot x_j\)。

\(\frac{b_i}{g(i)}=\sum\limits_{T|i}fr(T)\cdot q(T)\)

\(fr(i)\cdot q(i)=\sum\limits_{T|i}\mu(\frac{i}{T})\cdot \frac{b_T}{g(T)}\)

所以就可以求出\(q(i)\)了。

求出\(q(i)\)后,再次反演,

\(h(i)\cdot x_i=\sum\limits_{i|j}\mu(\frac{j}{i})\cdot q(j)\)

那么就很容易求出\(x_i\)了。

注意一下无解的情况即可。

#include <bits/stdc++.h>
using namespace std;
inline int Getint(){
    int x=0,f=1;char ch=getchar();
    while(!isdigit(ch))ch!='-'?:f=-1,ch=getchar();
    while(isdigit(ch))x=x*10+ch-'0',ch=getchar();
    return x*f;
}
typedef long long ll;
const int Maxn=100005,mod=998244353,pmod=mod-1;
int n,q,c,d,b[Maxn],ans[Maxn],h[Maxn],fr[Maxn],g[Maxn];
int mu[Maxn],Prime[Maxn];
bool vis[Maxn];
ll Pow(ll x,ll k){
    ll ret=1;
    while(k){
        if(k&1)ret=ret*x%mod;
        k>>=1;x=x*x%mod;
    }
    return ret;
}
void init(){
    mu[1]=1;
    for(int i=2;i<=100000;i++){
        if(!vis[i]){Prime[++Prime[0]]=i;mu[i]=-1;}
        for(int j=1;j<=Prime[0]&&i*Prime[j]<=100000;j++){
            vis[i*Prime[j]]=1;
            if(i%Prime[j]==0){mu[i*Prime[j]]=0;break;}
            mu[i*Prime[j]]=-mu[i];
        }
    }
    int mi=((c-d)%pmod+pmod)%pmod;
    for(int i=1;i<=100000;i++){
        int tmp=Pow(i,mi);
        for(int j=1;i*j<=100000;j++)
            fr[i*j]=(fr[i*j]+(ll)mu[j]*tmp)%mod;
    }
    for(int i=1;i<=100000;i++)g[i]=Pow(i,d);
}
void solve(){
    memset(h,0,sizeof(h));
    memset(ans,0,sizeof(ans));
    int mi=((-d)%pmod+pmod)%pmod;
    for(int i=1;i<=n;i++)b[i]=(ll)b[i]*Pow(i,mi)%mod;
    for(int i=1;i<=n;i++)
        for(int j=1;i*j<=n;j++)
            h[i*j]=(h[i*j]+(ll)mu[j]*b[i])%mod;
    for(int i=1;i<=n;i++){
        if(fr[i]==0&&h[i]!=0){puts("-1");return;}
        h[i]=(ll)h[i]*Pow(fr[i],mod-2)%mod;
    }
    for(int i=1;i<=n;i++)
        for(int j=1;i*j<=n;j++)
            ans[i]=(ans[i]+(ll)mu[j]*h[i*j])%mod;
    for(int i=1;i<=n;i++){
        if(g[i]==0&&ans[i]!=0){puts("-1");return;}
        if(g[i])ans[i]=(ll)ans[i]*Pow(g[i],mod-2)%mod;
        else ans[i]=0;
    }
    for(int i=1;i<=n;i++)cout<<(ans[i]+mod)%mod<<" \n"[i==n];
}
int main(){
    n=Getint();c=Getint();d=Getint();q=Getint();
    init();
    while(q--){
        for(int i=1;i<=n;i++)b[i]=Getint();
        solve();
    }
}

原文地址:https://www.cnblogs.com/Trrui/p/10005672.html

时间: 2024-10-29 05:02:07

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

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)} \

UOJ #62 怎样跑得更快

UOJ #62 怎样跑得更快 题目传送门 题意 大力水手问禅师:"大师,我觉得我光有力气是不够的.比如我吃菠菜可以让力气更大,但是却没有提升跑步的速度.请问怎样才能跑得更快?我试过吃白菜,没有效果." 禅师浅笑,答:"方法很简单,不过若想我教你,你先看看这道\(UOJ\) \(Round\)的\(C\)题." 令 \(p=998244353\)(\(7×17×223+17×17×223+1\),一个质数. 给你整数 \(n,c,d\).现在有整数\(x_1,-,x_

辛星让mysql跑的更快第一节之优化的方向和数据库建模

最近计划写一套书目,也就是关于mysql的优化的,那么首先在博客上写写,然后整理成pdf的文档的形式,当然也期待各位的关注了.对于mysql的优化是一个比较大的话题,可优化的地方也很多,大致想了一下,可以从这些地方下手. 首先就是硬件层次,包括选择合适的操作系统.选择合适的硬件,然后就是源码层次,不过虽然mysql是开源的,但是能够修改其源代码的公司虽然不少,但是也没有那么多,但是我们可以选择更加合适的编译器重新编译其源代码,然后就是设计到表的设计,也就数据库建模. 其次可以考虑使用一些其他技术

西蒙算法在量子计算机上“跑”得更快

来自南非的一组研究团队近日成功地在量子计算机上运行了西蒙算法(Simon’s algorithm),且这一算法在量子计算机上的运行表现比电子计算机表现得更好.相关论文刊登在<物理评论快报>上. 量子计算机是一种基于量子力学的计算设备,用来存储数据的对象是量子比特而非经典计算机的电子比特. 科学界普遍认为,由于量子计算机能够利用量子纠缠和叠加等独特的量子物理属性,在运行某些特定算法时,它会比现有计算机更为快速和高效.遗憾的是,到目前为止,还没有办法在量子计算机上运行这些量子算法来检验这一理论.

辛星让mysql跑得更快第二节之索引上部分

如果把我们的数据库信息当做一本书或者一个字典,那么索引可以理解为它的目录,如果我们创建一个优秀的目录,那么我们检索信息就会快得多,如果我们创建一个渣渣索引,也有可能拖垮整个系统. 索引我们分为四类,通常分为四大类型,即主键索引.全文索引.唯一索引.普通索引,这是按照索引的类型来分的.所谓主键索引,那就是当我们创建一张表的时候,如果我们指定了一个主键,那么它就自动成为主键索引,比如SQL语句如下(这里的id就自动成为了主键索引): create table xin(id int unsigned

让Python跑得更快

点击关注 异步图书,置顶公众号 每天与你分享 IT好书 技术干货 职场知识 Tips 参与文末话题讨论,即有机会获得异步图书一本. Python很容易学.你之所以阅读本文可能是因为你的代码现在能够正确运行,而你希望它能跑得更快.你可以很轻松地修改代码,反复地实现你的想法,你对这一点很满意.但能够轻松实现和代码跑得够快之间的取舍却是一个世人皆知且令人惋惜的现象.而这个问题其实是可以解决的. 有些人想要让顺序执行的过程跑得更快.有些人需要利用多核架构.集群,或者图形处理单元的优势来解决他们的问题.有

简单的几步让你的JQuery跑得更快

本文提供即刻提升你的脚本性能的十个步骤.不用担心,这并不是什么高深的技巧.人人皆可运用!这些技巧包括: 使用最新版本永盈会娱乐城 合并.最小化脚本 用for替代each 用ID替代class选择器 给选择器指定前后文 建立缓存 避免DOM操作 避免使用concat(),利用join()处理长字串 返回false值 利用小抄和参考文档 使用最新版本 jQuery一直处于不断的开发和改进过程中. John 和他的团队不断研究着提升程序性能的新方法. 一点题外话,几个月前他还发布了Sizzle,一个据

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

Node.js 受益于它的事件驱动和异步的特征,已经很快了.但是,在现代网络中只是快是不行的.如果你打算用 Node.js 开发你的下一个Web 应用的话,那么你就应该无所不用其极,让你的应用更快,异常的快.本文将介绍 10 条,经过检验得知可大大提高 Node 应用的技巧.废话不多说,让我们逐条来看看.创建 Web 应用的时候,你可能要多次调用内部 API 来获取各种数据.比如说,假设在 Dashboard 页面上,你要执行下面这几个调用: 开源中国匿名会员 翻译于 4天前 4人顶 顶 翻译的

uoj#62 怎样跑的更快 (莫比乌斯反演)

题目链接:http://uoj.ac/problem/62 推式子呀推式子 发现我对莫比乌斯反演一无所知qaq 预处理出要用的数组,然后反演反演反演就好啦 #include<cstdio> #include<cstring> #include<iostream> #include<algorithm> #include<queue> #include<stack> #include<cmath> using namespa