P4240 毒瘤之神的考验

news2024/11/26 8:35:44

毒瘤之神的考验 - 洛谷

\sum_{i=1}^{n}\sum_{j=1}^{m}\varphi (ij) \qquad 1-1

定义\varphi (i)=i*\prod_{p|i}^{}\frac{p-1}{p}

猜想\varphi (ij)\varphi (i)\varphi (j)有关

\varphi (ij)=\frac{i*\prod_{p|i}^{}\frac{p-1}{p}*j*\prod_{p|j}^{}\frac{p-1}{p}}{\prod_{p|gcd(i,j)}^{}*\frac{p-1}{p}} \qquad 1-2

\varphi (i)*\varphi(j)=i*\prod_{p|i}^{}*\frac{p-1}{p}*j*\prod_{p|j}^{}*\frac{p-1}{p} \qquad 1-3

发现上式1-1 上下两边乘gcd(i,j)有

\varphi(ij)=\frac{\varphi(i)*\varphi(j)*gcd(i,j)}{\varphi(gcd(i,j))}\qquad 1-4

带入1-1有

\sum_{i=1}^{n}\sum_{j=1}^{m}\frac{\varphi(i)*\varphi(j)*gcd(i,j)}{\varphi(gcd(i,j))}\qquad 2-1

化简 n<m

\sum_{k=1}^{n}\sum_{i=1}^{n}\sum_{j=1}^{m}\frac{\varphi(i)*\varphi(j)*k*[gcd(i,j)=k]}{\varphi(k)}\qquad 2-2

\sum_{k=1}^{n}\sum_{ik=1}^{n}\sum_{jk=1}^{m}\frac{\varphi(ik)*\varphi(jk)*k*[gcd(i,j)=1]}{\varphi(k)}\qquad 2-3

\sum_{k=1}^{n}\frac{k}{\varphi(k)}\sum_{i=1}^{n/k}\sum_{j=1}^{m/k}\varphi(ik)*\varphi(jk)*[gcd(i,j)=1]\qquad 2-4

\sum_{k=1}^{n}\frac{k}{\varphi(k)}\sum_{e=1}^{n/k}\sum_{ie=1}^{n/k}\sum_{je=1}^{m/k}\varphi(ike)*\varphi(jke)*\mu (e)\qquad 2-5

\sum_{k=1}^{n}\frac{k}{\varphi(k)}\sum_{e=1}^{n/k}\sum_{i=1}^{n/ke}\sum_{j=1}^{m/ke}\varphi(ike)*\varphi(jke)*\mu (e)\qquad 2-6

经典代换T=ke  e=T/k

\sum_{T=1}^{n}\sum_{k|T}^{}\frac{k}{\varphi(k)}*\mu (\frac{T}{k})\sum_{i=1}^{n/T}\sum_{j=1}^{m/T}\varphi(iT)*\varphi(jT)\qquad 2-7

然后化简不了了

这个时候我们可以把一部分看出一个整体

f(x)=\sum_{k|x}^{}\frac{k*\mu(\frac{x}{k})}{\varphi(k)}\qquad 2-8

g(x,y)=\sum_{i=1}^{y}\varphi(ix) \qquad2-9-1

分析这两个函数,发现f(x) 可以在O(nlnn)下预处理出来

g(x,y)有以下递推式

g(x,y)=g(x-1,y)+\varphi(xy)\qquad 2-9-2 

因此也可以在O(nlnn)下处理出来

于是莫队O(nlnn+qsqrt(n)lnn)

#include <bits/stdc++.h>

#define int long long
#define INF (1ll<<60)
#define eps 1e-6
using namespace std;
typedef long long ll;
typedef long long LL;
typedef pair<int, int> pii;
typedef vector<int> vi;
typedef unsigned long long ull;
typedef vector<vector<int> > vii;
typedef vector<vector<vector<int> > > viii;
typedef vector<ll> vl;
typedef vector<vector<ll> > vll;
typedef vector<double> vd;
typedef vector<vector<double> > vdd;
#define time mt19937_64 rnd(chrono::steady_clock::now().time_since_epoch().count());//稳定随机卡牛魔 ull
const int N = 1e5 + 9;
const int mod = 998244353;
int phi[N], mu[N], vis[N], p[N], cnt;
ll t, ans[N], res;
ll f[N];
int inv[N];
vi g[N], d[N];
int L[N],R[N],pos[N];

struct Q {
    int n, m, id;

    friend bool operator<(Q x, Q y) {
        return x.n / t == y.n / t ? ((x.n / t) & 1) ? y.m < x.m : x.m < y.m : x.n < y.n;
    }
} que[N];

void init(int n) {
    //mu,phi
    mu[1] = 1, phi[1] = 1;
    for (int i = 2; i <= n; i++) {
        if (!vis[i]) p[++cnt] = i, mu[i] = -1, phi[i] = i - 1;
        for (int j = 1; j <= cnt && i * p[j] <= n; j++) {
            int t = i * p[j];
            vis[t] = 1;
            if (i % p[j]) mu[t] = -mu[i], phi[t] = phi[i] * (p[j] - 1);
            else {
                phi[t] = phi[i] * p[j];
                break;
            }
        }
    }
    //inv
    inv[1] = 1;
    for (ll i = 2; i <= n; i++) {
        inv[i] = inv[mod % i] * (mod - mod / i) % mod;
    }
    //g(x,y)
    for (ll i = 1; i <= n; i++) {
        g[i].resize(n / i + 2);
        for (ll j = 1; j <= n / i; j++) {
            //前缀和推出
            g[i][j] = (g[i][j - 1] + phi[i * j]) % mod;
        }
    }
    //f(x)
    for (ll i = 1; i <= n; i++) {
        for (ll j = i; j <= n; j += i) {
            f[j] = f[j] % mod + i * inv[phi[i]] % mod * mu[j / i] % mod;
            d[j].push_back(i);//j的约数
        }
    }
}

void update(ll a, ll b, ll w) {
    for (ll i = 0; i < d[a].size(); ++i) {
        res = (res + 1ll * w % mod * phi[a] % mod * g[d[a][i]][b / d[a][i]] % mod * f[d[a][i]] % mod) % mod;
    }
    res = (res + mod) % mod;
}

signed main() {
    ios::sync_with_stdio(false);
    cin.tie(nullptr), cout.tie(nullptr);
    init(N - 9);
    int q;
    cin >> q;
    t = sqrt(q);
    for (int i = 1; i <= q; i++) {
        int n, m;
        cin >> n >> m;
        if (n > m) {
            swap(n, m);
        }
        que[i] = {n, m, i};
    }
    sort(que + 1, que + 1 + q);
    ll l = 0, r = 0;
    for (int i = 1; i <= q; i++) {
        while (l < que[i].n) update(++l, r, 1);
        while (r < que[i].m) update(++r, l, 1);
        while (l > que[i].n) update(l--, r, -1);
        while (r > que[i].m) update(r--, l, -1);
        ans[que[i].id] = res % mod;
    }
    for (int i = 1; i <= q; i++) {
        cout << ans[i] << '\n';
    }
    return 0;
}

接着推

把两个函数带入2-7可以得到

\sum_{T=1}^{n}f(T)*g(T,n/T)*g(T,m/T) \qquad 3-1

设整体一个函数有

h(n,m,T)=\sum_{k=1}^{T}f(k)*g(k,n/k)*g(k,m/k) \qquad 3-1-1

整除分块得到部分答案

h(n,m,r)-h(n,m,l-1)=ansi\qquad 3-1-2

O(n^{2}lnn)前缀和处理出答案

h(n,m,x)=h(n,m,x-1)+f(x)*g(x,n/x)*g(x,m/x) \,3-2 

现在我们有两种方案

1.O(nlnn)预处理,O(n)回答  TLE

2.O(n^{2}lnn)预处理,O(sqrt(n)) 回答 MLE+TLE

因此用根号分治来平衡时间

设定一个阈值 k

1.<=t预处理  暴力 O(nlnn+\frac{tn}{k})

2.>t 处理过的整块算 整除分块 O(nklnk+tsqrt(n))

最优的k  (klnk+\frac{t}{k})min  t=1e4 k=47

k=47-500 都能过 还#define int long long 了 !   

#include <bits/stdc++.h>
#define int long long
#define INF (1ll<<60)
#define eps 1e-6
using namespace std;
typedef long long ll;
typedef long long LL;
typedef pair<int, int> pii;
typedef vector<int> vi;
typedef unsigned long long ull;
typedef vector<vector<int> > vii;
typedef vector<vector<vector<int> > > viii;
typedef vector<ll> vl;
typedef vector<vector<ll> > vll;
typedef vector<double> vd;
typedef vector<vector<double> > vdd;
#define time mt19937_64 rnd(chrono::steady_clock::now().time_since_epoch().count());//稳定随机卡牛魔 ull
const int N = 1e5 + 9;
const int mod = 998244353;
const int B = 47;
int phi[N], mu[N], vis[N], p[N], cnt;
int f[N], inv[N];
vi g[N], h[B + 5][B + 5];

void add(int &x, int y) { x = x + y >= mod ? x + y - mod : x + y; }

void init(int n) {
    //mu,phi
    mu[1] = 1, phi[1] = 1;
    for (int i = 2; i <= n; i++) {
        if (!vis[i]) p[++cnt] = i, mu[i] = -1, phi[i] = i - 1;
        for (int j = 1; j <= cnt && i * p[j] <= n; j++) {
            int t = i * p[j];
            vis[t] = 1;
            if (i % p[j]) mu[t] = -mu[i], phi[t] = phi[i] * (p[j] - 1);
            else {
                phi[t] = phi[i] * p[j];
                break;
            }
        }
    }
    //inv
    inv[1] = 1;
    for (ll i = 2; i <= n; i++) {
        inv[i] = inv[mod % i] * (mod - mod / i) % mod;
    }
    //g(x,y)
    for (ll i = 1; i <= n; i++) {
        g[i].resize(n / i + 5);
        for (ll j = 1; j <= n / i; j++) {
            //前缀和推出
            g[i][j] = (g[i][j - 1] + phi[i * j]) % mod;
        }
    }
    //f(x)
    for (ll i = 1; i <= n; i++) {
        for (ll j = i; j <= n; j += i) {
            f[j] = f[j] % mod + i * inv[phi[i]] % mod * mu[j / i] % mod;
        }
    }
    //h(n,m,t)
    for (int i = 1; i <= B; i++) {
        for (int j = i; j <= B; j++) {
            h[i][j].resize(n / j + 5);
            for (int t = 1; t <= n / j; t++) {
                h[i][j][t] = (h[i][j][t - 1] + 1ll * f[t] * g[t][i] % mod * g[t][j] % mod) % mod;
            }
        }
    }

}


signed main() {
    ios::sync_with_stdio(false);
    cin.tie(nullptr), cout.tie(nullptr);
    init(N - 9);
    auto solve = [&](int n, int m) {
        if (n > m) {
            swap(n, m);
        }
        int res = 0;
        //根号分治
        for (int i = 1; i <= m / B; i++) {
            add(res, 1ll * f[i] * g[i][n / i] % mod * g[i][m / i] % mod);
        }
        for (int l = m / B + 1, r; l <= n; l = r + 1) {
            r = min(n / (n / l), m / (m / l));
            add(res, (h[n / l][m / l][r] - h[n / l][m / l][l - 1] + mod) % mod);
        }
        return res;
    };
    int q;
    cin >> q;
    while (q--) {
        int n, m;
        cin >> n >> m;
        cout << solve(n, m) << '\n';
    }
    return 0;
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2190296.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

三、流程控制

流程控制 选择结构&#xff08;if-else&#xff09;选择结构&#xff08;when&#xff09;循环结构&#xff08;for&#xff09;循环结构&#xff08;while&#xff09; 经过前面的学习&#xff0c;我们知道&#xff0c;程序都是从上往下依次运行的&#xff0c;但是&#xff0c…

事件抽取(Event Extraction, EE)

一、引言 事件抽取&#xff08;Event Extraction, EE&#xff09;是信息抽取领域中的一个重要任务&#xff0c;旨在从非结构化文本中识别和抽取事件相关的信息。事件抽取通常包括识别事件触发词、事件类型以及事件中的参与者、时间、地点等元素&#xff0c;最终将这些信息结构…

【进阶OpenCV】 (4)--图像拼接

文章目录 图像拼接1. 读取图片2. 计算图片特征点及描述符3. 建立暴力匹配器4. 特征匹配5. 透视变换6. 图像拼接 总结 图像拼接 图像拼接是一项将多张有重叠部分的图像&#xff08;这些图像可能是不同时间、不同视角或者不同传感器获得的&#xff09;拼成一幅无缝的全景图或高分…

论文翻译 | Model-tuning Via Prompts Makes NLP Models Adversarially Robust

摘要 近年来&#xff0c;NLP从业者集中于以下实践:(i)导入现成的预训练(掩码)语言模型;(ii)在CLS令牌的隐藏表示(随机初始化权重)上附加多层感知器;(iii)在下游任务(MLP-FT)上微调整个模型。这一过程在标准的NLP基准上产生了巨大的收益&#xff0c;但这些模型仍然很脆弱&#x…

mysql单表查询·3

准备好表 create table product(id int primary key,name varchar(32),price double,category varchar(32) ); # 插入数据 INSERT INTO product(id,name,price,category) VALUES(1,联想,5000,c001); INSERT INTO product(id,name,price,category) VALUES(2,海尔,3000,c001); I…

加密与安全_HOTP一次性密码生成算法

文章目录 HOTP 的基础原理HOTP 的工作流程HOTP 的应用场景HOTP 的安全性安全性增强措施Code生成HOTP可配置项校验HOTP可拓展功能计数器&#xff08;counter&#xff09;计数器在客户端和服务端的作用计数器的同步机制客户端和服务端中的计数器表现服务端如何处理计数器不同步计…

好用的苹果笔推荐!五大高品质王者款!附避坑宝典助你选购无忧!

现在平板和电容笔在一定程度上可以替代传统的笔和纸&#xff0c;很多用户在购置iPad后&#xff0c;急需找到一款好用的电容笔。但由于苹果原装笔的价格太过高昂&#xff0c;让许多人不得不选择平替电容笔&#xff01;下面我就为大家推荐五款高品质的电容笔&#xff0c;并分享几…

单细胞hdWGCNA分析学习和整理

hdWGCNA的分析逻辑是跟bulkRNA数据中的WGCNA基本一样&#xff0c;只是hdWGCNA中多了一步metacell过程&#xff0c;有助于减少无用的信息(单细胞数据有很多零值&#xff0c;会影响分析结果)。 WGCNA的基础信息可见既往推文: https://mp.weixin.qq.com/s/2Q37RcJ1pBy_WO1Es8upIg…

二分查找算法专题(2)

找往期文章包括但不限于本期文章中不懂的知识点&#xff1a; 个人主页&#xff1a;我要学编程(ಥ_ಥ)-CSDN博客 所属专栏&#xff1a; 优选算法专题 对于二分查找算法不是很了解或者只了解一部分的小伙伴一定要去看下面这篇博客&#xff1a;二分查找算法的介绍与另外一种查找方…

【EcoNAS: Finding Proxies for Economical Neural Architecture Search】读后感

鄙人近日阅读了来自 CVPR2020 的一篇论文, 在这里与大家分享一下读后感, 有些东西可能不一定正确, 还望大家指正. Exploration Study 进化算法是 NAS 中一种常用的搜索算法, 使用进化算法时, 如果将每一个候选网络训练到完全收敛来评估性能的话, 需要耗费大量的资源 (时间, G…

现代身份和访问管理 IAM 如何降低风险

您的公司是否仍在使用 1998 年时的身份管理系统&#xff1f;仅凭用户名和密码就能登录本地网络并访问几乎所有资源吗&#xff1f; 虽然大多数企业已经转向现代身份和访问管理(IAM) 平台&#xff0c;但成千上万的企业和其他组织仍然依赖过时的用户名/密码系统。 如果你看一下传…

Ubuntu18.04配置OpenPCDet并运行demo过程记录

一、概述 因为最近需要配置OpenPCDet&#xff0c;发现在配置过程中存在诸多的问题需要解决&#xff0c;将过程中所遇到的问题进行记录保存。 二、具体配置过程 &#xff08;一&#xff09;参考链接 因为中间遇到了很多问题&#xff0c;参考了很多不少相应的博客进行问题解决。…

【Unity】unity安卓打包参数(个人复习向/有不足之处欢迎指出/侵删)

1.Texture Compression 纹理压缩 设置发布后的纹理压缩格式 Use Player Settings:使用在播放器设置中设置的纹理压缩格式 ETC&#xff1a;使用ETC格式&#xff08;兼容&#xff09; ETC2&#xff1a;使用ETC2格式&#xff08;很多设备不支持&#xff09; ASTC&#xff1a;使用…

使用JavaScript写一个网页端的四则运算器

目录 style(内联样式表部分) body部分 html script 总的代码 网页演示 style(内联样式表部分) <style>body {font-family: Arial, sans-serif;display: flex;justify-content: center;align-items: center;height: 100vh;background-color: #f0f0f0;}.calculator {…

c++ 指针传参

// // Created by 徐昌真 on 2024/10/4. // #include <iostream>//函数的值传递 void swap(int a, int b){ //只是单纯的改变了函数内部a b的值 在main函数内值并不会改变 因为值存在地址里面 而地址里面的值要通过指针来改变int temp;temp a;a b;b temp; }//函数的址…

Oracle架构之表空间详解

文章目录 1 表空间介绍1.1 简介1.2 表空间分类1.2.1 SYSTEM 表空间1.2.2 SYSAUX 表空间1.2.3 UNDO 表空间1.2.4 USERS 表空间 1.3 表空间字典与本地管理1.3.1 字典管理表空间&#xff08;Dictionary Management Tablespace&#xff0c;DMT&#xff09;1.3.2 本地管理方式的表空…

8647 实现图的存储结构

### 思路 1. 读取输入的顶点个数n和边的条数m。 2. 初始化一个n*n的邻接矩阵&#xff0c;所有元素初始为0。 3. 读取每条边的信息&#xff0c;更新邻接矩阵对应位置为1。 4. 输出邻接矩阵。 ### 伪代码 1. 读取n和m。 2. 初始化n*n的邻接矩阵matrix&#xff0c;所有元素为0。 …

CSS列表和超链接的使用(8个案例+代码+效果图+素材)

目录 1.无序列表ul 案例:定义不同type的li 1.代码 2.效果 2.有序列表ol type 取值 start属性 value 案例:定义不同类型的有序列表 1.代码 2.效果 3.定义列表dl 1.代码 2.效果 4.list-style-type属性 list-style-type的取值 案例:list-type的使用 1.代码 2.效果 5.list-style-im…

关于OJ平台的一个代码小问题 ——

目录 一、关于OJ平台的一个代码小问题 1、将OJ代码复制粘贴到vs上 2、创建测试方法&#xff0c;调用本次要调试的目标方法 3、利用vs调试工具排查代码问题 一、关于OJ平台的一个代码小问题 思考&#xff1a;OJ代码有bug怎么办&#xff1f; 答&#xff1a;VS调试技能用起来 …

G. Gears (2022 ICPC Southeastern Europe Regional Contest. )

G. Gears 思路&#xff1a; 本身这个题并不难&#xff0c;奈何卡了很久后看了题解才做出来&#xff0c;感觉自己好笨。 很容易想到的是&#xff0c;只要确定了一个齿轮的位置&#xff0c;其他齿轮的位置都可以直接推出来。所以当前目标是如何确定第一个齿轮的位置。 令 x [ i …