「VMware校园挑战赛」小V的和式
Description
给定 \(n,m\) ,求
\]
数据范围 \(1\le n,m\le 10^9\),答案对 \(998244353\) 取模。
Solution
约定
\(S_k(n)=\sum\limits_{i=1}^{n} i^k\)
若 \(n>m\) ,则交换 \(n,m\) ,保证 \(n\le m\)。
拆上下指标
先对上下指标做一下处理,得:
\]
\]
\]
考虑拆开 \([x_1<x_2][y_1<y_2]\) :
\]
\]
回带到原来式子,得到:
\(2[0\le x_1<x_2][0\le y_1<y_2]\)
\(-2([0=x_1<x_2][0\le y_1<y_2]+[0\le x_1<x_2][0=y_1<y_2])\)
\(+2[0=x_1<x_2][0=y_1<y_2]\)
\(+2[x_1>x_2][y_1<y_2]\)
\(+2([x_1<x_2][y_1=y_2]+[x_1=x_2][y_1<y_2])\)
\(+[x_1=x_2][y_1=y_2]\)
所以分别求出这 \(6\) 种情形即可,下面开始推导。
1. \([0\le x_1<x_2][0\le y_1<y_2]\)
即求
\]
\]
- 引理1
对于所有的 \(a \in [0,y), b\in[0,x)\),\((ax+by)\ mod\ (xy)\) 将集合 \(S=\{ (a,b) | 0\le a<y, 0\le b<x\}\) 映射到 \(T=\{ k\times gcd(a,b) | 0\le k< \frac{ab}{gcd(a,b)}\}\) ,并且对于 \(T\) 中的每一元素恰好有 \(gcd(a,b)\) 个原象。
感性理解一下即可,故:
\]
将前半部分拎出来:
\]
\]
\]
\]
其中 \(G_1(n)=n^3 \sum\limits_{d|n} \mu(d)d\)
因此
\]
2. \([0= x_1<x_2][0\le y_1<y_2]\)
即求
\]
\]
其实还有对称的 \([0\le x_1<x_2][0=y_1<y_2]\) ,推导类似。
3. \([0=x_1<x_2][0=y_1<y_2]\)
\]
4. \([x_1>x_2][y_1<y_2]\)
\]
\]
\]
\]
\]
\]
\]
其中 \(G_2(n)=n^2\sum\limits_{d|n}\mu(d)d\)
\(G_3(n)=n\sum\limits_{d|n}\mu(d)d\)
5. \([x_1=x_2][y_1<y_2]\)
\]
\]
可以发现 \(f_5\) 和 \(f_2\) 的式子完全一致,且符号相反,因此可以抵消。
显然对于另一半对称的式子也是如此。
6. \([x_1=x_2][y_1=y_2]\)
\]
合并
答案为
\]
\]
因此我们只需要快速求出 \(G_1(n),G_2(n),G_3(n)\) 的前缀和即可。
杜教筛
考虑杜教筛,以 \(G_1(n)\) 为例。
\(f(n)=n^3\sum\limits_{d|n}\mu(d)d\)
记 \(S(n)=\sum\limits_{i=1}^{n}f(i)\)
则 \(S(n)=\sum\limits_{i=1}^{n}i^3\sum\limits_{d|i}\mu(d)d\)
\(=\sum\limits_{d=1}^{n}\mu(d)d^4S_3(\lfloor \frac{n}{d}\rfloor)\)
所以我们需要杜教筛求 \(f'(i)=\mu(i)i^4\) 的前缀和。
考虑 \(g=ID^4\) ,则 \(h(n)=f'*g=[n==1]\)
故 \(S(n)=1-\sum\limits_{i=2}^{n}i^4 \times S(\lfloor \frac{n}{i}\rfloor)\)
实现
时间复杂度:\(O(n^{\frac{5}{6}})\)
空间复杂度:\(O(n^{\frac{2}{3}})\)
#pragma GCC optimize(2)
#pragma GCC optimize(3)
#pragma GCC optimize("Ofast")
#pragma GCC optimize("inline")
#pragma GCC optimize("-fgcse")
#pragma GCC optimize("-fgcse-lm")
#pragma GCC optimize("-fipa-sra")
#pragma GCC optimize("-ftree-pre")
#pragma GCC optimize("-ftree-vrp")
#pragma GCC optimize("-fpeephole2")
#pragma GCC optimize("-ffast-math")
#pragma GCC optimize("-fsched-spec")
#pragma GCC optimize("unroll-loops")
#pragma GCC optimize("-falign-jumps")
#pragma GCC optimize("-falign-loops")
#pragma GCC optimize("-falign-labels")
#pragma GCC optimize("-fdevirtualize")
#pragma GCC optimize("-fcaller-saves")
#pragma GCC optimize("-fcrossjumping")
#pragma GCC optimize("-fthread-jumps")
#pragma GCC optimize("-funroll-loops")
#pragma GCC optimize("-fwhole-program")
#pragma GCC optimize("-freorder-blocks")
#pragma GCC optimize("-fschedule-insns")
#pragma GCC optimize("inline-functions")
#pragma GCC optimize("-ftree-tail-merge")
#pragma GCC optimize("-fschedule-insns2")
#pragma GCC optimize("-fstrict-aliasing")
#pragma GCC optimize("-fstrict-overflow")
#pragma GCC optimize("-falign-functions")
#pragma GCC optimize("-fcse-skip-blocks")
#pragma GCC optimize("-fcse-follow-jumps")
#pragma GCC optimize("-fsched-interblock")
#pragma GCC optimize("-fpartial-inlining")
#pragma GCC optimize("no-stack-protector")
#pragma GCC optimize("-freorder-functions")
#pragma GCC optimize("-findirect-inlining")
#pragma GCC optimize("-fhoist-adjacent-loads")
#pragma GCC optimize("-frerun-cse-after-loop")
#pragma GCC optimize("inline-small-functions")
#pragma GCC optimize("-finline-small-functions")
#pragma GCC optimize("-ftree-switch-conversion")
#pragma GCC optimize("-foptimize-sibling-calls")
#pragma GCC optimize("-fexpensive-optimizations")
#pragma GCC optimize("-funsafe-loop-optimizations")
#pragma GCC optimize("inline-functions-called-once")
#pragma GCC optimize("-fdelete-null-pointer-checks")
#include<bits/stdc++.h>
using namespace std;
#define rint register int
#define rep(i,l,r) for(rint i=l;i<=r;i++)
#define per(i,l,r) for(rint i=l;i>=r;i--)
#define ll long long
#define ull unsigned long long
#define pii pair<int,int>
#define pll pair<ll,ll>
#define pb push_back
#define fir first
#define sec second
#define mset(s,t) memset(s,t,sizeof(s))
template<typename T1,typename T2>void ckmin(T1 &a,T2 b){if(a>b)a=b;}
template<typename T1,typename T2>void ckmax(T1 &a,T2 b){if(a<b)a=b;}
template<typename T>T gcd(T a,T b){return b?gcd(b,a%b):a;}
int read(){
int x=0,f=0;
char ch=getchar();
while(!isdigit(ch))f|=ch=='-',ch=getchar();
while(isdigit(ch))x=10*x+ch-'0',ch=getchar();
return f?-x:x;
}
const int N=10000005;
const int mod=998244353;
ll qpow(ll a,ll b=mod-2){
ll res=1;
a%=mod;
while(b>0){
if(b&1)res=res*a%mod;
a=a*a%mod;
b>>=1;
}
return res;
}
const ll inv2=qpow(2);
const ll inv4=qpow(4);
const ll inv6=qpow(6);
const ll inv8=qpow(8);
const ll inv30=qpow(30);
int mu[N],g1[N],g2[N],g3[N];
bool vis[N];
int pr[N>>3],len,L=1e7;
void init(int n){
mu[1]=1;
for(register int i=2;i<=n;i++){
if(!vis[i])pr[len++]=i,mu[i]=-1;
for(register int j=0;j<len&&pr[j]*i<=n;j++){
vis[pr[j]*i]=1;
if(i%pr[j]==0)break;
mu[pr[j]*i]=-mu[i];
}
}
rep(i,1,n){
g1[i]=(g1[i-1]+1ll*i*i%mod*i%mod*i%mod*mu[i])%mod;
g2[i]=(g2[i-1]+1ll*i*i%mod*i%mod*mu[i])%mod;
g3[i]=(g3[i-1]+1ll*i*i%mod*mu[i])%mod;
}
}
ll S1(ll x){
x%=mod;
return x*(x+1)%mod*inv2%mod;
}
ll S2(ll x){
x%=mod;
return x*(x+1)%mod*(2*x+1)%mod*inv6%mod;
}
ll S3(ll x){
x%=mod;
return S1(x)*S1(x)%mod;
}
ll S4(ll x){
x%=mod;
return x*(x+1)%mod*(2*x+1)%mod*(3*x*x%mod+3*x-1)%mod*inv30%mod;
}
int n,m;
unordered_map<int,ll>Map1,Map2,Map3;
ll GG1(int n){
if(n<=L)return g1[n];
if(Map1[n])return Map1[n];
ll ans=1;
for(int i=2,j;i<=n;i=j+1){
j=n/(n/i);
ans=(ans-GG1(n/i)*(S4(j)-S4(i-1)+mod))%mod;
}
return Map1[n]=(ans%mod+mod)%mod;
}
ll GG2(ll n){
if(n<=L)return g2[n];
if(Map2[n])return Map2[n];
ll ans=1;
for(int i=2,j;i<=n;i=j+1){
j=n/(n/i);
ans=(ans-GG2(n/i)*(S3(j)-S3(i-1)+mod))%mod;
}
return Map2[n]=(ans%mod+mod)%mod;
}
ll GG3(ll n){
if(n<=L)return g3[n];
if(Map3[n])return Map3[n];
ll ans=1;
for(int i=2,j;i<=n;i=j+1){
j=n/(n/i);
ans=(ans-GG3(n/i)*(S2(j)-S2(i-1)+mod))%mod;
}
return Map3[n]=(ans%mod+mod)%mod;
}
unordered_map<int,ll>map4,map5,map6;
ll G1(int n){
if(map4[n])return map4[n];
ll ans=0;
for(int i=1,j;i<=n;i=j+1){
j=n/(n/i);
ans=(ans+(GG1(j)-GG1(i-1)+mod)*S3(n/i))%mod;
}
return map4[n]=ans;
}
ll G2(int n){
if(map5[n])return map5[n];
ll ans=0;
for(int i=1,j;i<=n;i=j+1){
j=n/(n/i);
ans=(ans+(GG2(j)-GG2(i-1)+mod)*S2(n/i))%mod;
}
return map5[n]=ans;
}
ll G3(int n){
if(map6[n])return map6[n];
ll ans=0;
for(int i=1,j;i<=n;i=j+1){
j=n/(n/i);
ans=(ans+(GG3(j)-GG3(i-1)+mod)*S1(n/i))%mod;
}
return map6[n]=ans;
}
ll f1(){
ll ans=0;
for(int i=1,j;i<=n;i=j+1){
j=min(n/(n/i),m/(m/i));
ans=(ans+S2(n/i)*S2(m/i)%mod*(G1(j)-G1(i-1)+mod))%mod;
}
ans=ans*inv2%mod;
ans=(ans+mod-S1(n)*S1(m)%mod*inv2%mod)%mod;
return (ans+mod)%mod;
}
ll f4(){
ll ans=0;
for(int i=1,j;i<=n;i=j+1){
j=min(n/(n/i),m/(m/i));
ans=(ans+S2(n/i)*S2(m/i)%mod*(G1(j)-G1(i-1)+mod))%mod;
ans=(ans-(S1(n/i)*S2(m/i)+S2(n/i)*S1(m/i))%mod*(G2(j)-G2(i-1)+mod))%mod;
ans=(ans+S1(n/i)*S1(m/i)%mod*(G3(j)-G3(i-1)+mod))%mod;
}
ans=ans*inv4%mod;
return (ans+mod)%mod;
}
int main(){
init(L);
//n=1e9,m=1e9;
scanf("%d%d",&n,&m);
if(n>m)swap(n,m);
printf("%lld\n",2ll*(f1()+f4())%mod);
return 0;
}
关于对 \([0= x_1<x_2][0\le y_1<y_2]\) 的彩(推)蛋(导)
qwq 其实是因为我一开始没意料到能相互抵消,所以推了不少,这里就保留一下好了。
\]
\]
右边 \(y_2\) 的式子,令 \(t=m/dk\) ,经化简得
\]
因此:
\]
然后令 \(T=dk\) 化简一下就行了。。。
「VMware校园挑战赛」小V的和式的更多相关文章
- Loj #2324. 「清华集训 2017」小 Y 和二叉树
Loj #2324. 「清华集训 2017」小 Y 和二叉树 小Y是一个心灵手巧的OIer,她有许多二叉树模型. 小Y的二叉树模型中,每个结点都具有一个编号,小Y把她最喜欢的一个二叉树模型挂在了墙上, ...
- [LOJ#2323]「清华集训 2017」小Y和地铁
[LOJ#2323]「清华集训 2017」小Y和地铁 试题描述 小Y是一个爱好旅行的OIer.一天,她来到了一个新的城市.由于不熟悉那里的交通系统,她选择了坐地铁. 她发现每条地铁线路可以看成平面上的 ...
- Vue+WebSocket+ES6+Canvas 制作「你画我猜」小游戏
Vue+WebSocket+ES6+Canvas 制作「你画我猜」小游戏 转载 来源:jrainlau 链接:https://segmentfault.com/a/1190000005804860 项 ...
- loj #2325. 「清华集训 2017」小Y和恐怖的奴隶主
#2325. 「清华集训 2017」小Y和恐怖的奴隶主 内存限制:256 MiB时间限制:2000 ms标准输入输出 题目类型:传统评测方式:文本比较 题目描述 "A fight? Co ...
- [LOJ#2324]「清华集训 2017」小Y和二叉树
[LOJ#2324]「清华集训 2017」小Y和二叉树 试题描述 小Y是一个心灵手巧的OIer,她有许多二叉树模型. 小Y的二叉树模型中,每个结点都具有一个编号,小Y把她最喜欢的一个二叉树模型挂在了墙 ...
- LOJ2324. 「清华集训 2017」小 Y 和二叉树【贪心】【DP】【思维】【好】
LINK 思路 首先贪新的思路是处理出以一个节点为根所有儿子的子树中中序遍历起始节点最小是多少 然后这个可以两次dfs来DP处理 然后就试图确定中序遍历的第一个节点 一定是siz<=2的编号最小 ...
- LOJ2324「清华集训 2017」小Y和二叉树
题目链接 瞎jb贪一发就过了.首先度数<=2且编号最小的点一定是中序遍历最靠前的点,我们从这个点开始dfs一遍算出子树中度数<=2且编号最小的点记为\(f(i)\),然后从这个点开始一步一 ...
- 【loj2325】「清华集训 2017」小Y和恐怖的奴隶主 概率dp+倍增+矩阵乘法
题目描述 你有一个m点生命值的奴隶主,奴隶主受伤未死且当前随从数目不超过k则再召唤一个m点生命值的奴隶主. T次询问,每次询问如果如果对面下出一个n点攻击力的克苏恩,你的英雄期望会受到到多少伤害. 输 ...
- 【费用流】loj#545. 「LibreOJ β Round #7」小埋与游乐场
好像现在看来这个缩点的思路挺清晰啊 题目描述 有两个非负整数组成的可重集合 $A$ 和 $B$. 现在你可以对 $A$ 中至多 $k$ 个元素进行操作.操作方法为:设你准备操作且未被操作过的 $A$ ...
随机推荐
- 获取iframe引入页面内的元素
在web开发中,经常会用到iframe,难免会碰到需要在父窗口中使用iframe中的元素.或者在iframe框架中使用父窗口的元素.js在父窗口中获取iframe中的元素1. 格式:window ...
- CentOS7 Network Setting
#display devices[root@localhost ~]# nmcli d #set ipv4 address[root@localhost ~]# nmcli c modify eth0 ...
- Wireshark-过滤器-数据包解析
目录 过滤器 数据包解析 参考 推荐阅读: https://www.cnblogs.com/zwtblog/tag/计算机网络/ 过滤器 显示过滤器 和 捕获过滤器,俩者使用非常类似. 在Wiresh ...
- Python入门-分支循环结构
编写代码的过程中,除了基本的变量,数据类型,在实际开发中,大量代码是根据判断条件,进而选择不同的的向前运行方式. 这些向前的运行方式基本分为两种:分支结构,循环结构 1.分支结构 if单分支结构 # ...
- Node.js躬行记(17)——UmiJS版本升级
在2020年我刚到公司的时候,公司使用的版本还是1.0,之后为了引入微前端,迫不得已被动升级. 一.从 1.0 到 2.0 在官方文档中,有专门一页讲如何升级的,这个用户体验非常好. 一个清单列的非常 ...
- JetBrains Rider C# 学习②
前言 C#从入门到精通 链接:https://pan.baidu.com/s/1UveJI_f-c5Dul3GLIICRHg 提取码:1314 C#入门课程 刘铁猛 链接:https://pan.ba ...
- 对比学习 ——simsiam 代码解析。
目录 1 : 事先准备 . 2 : 代码阅读. 2.1: 数据读取 2.2: 模型载入 3 训练过程: 4 测试过程: 5 :线性验证 6 : 用自己数据集进行对比学习. 第一: 改数据集 : ...
- 龙智被评估为CMMI [3] 级
2022年3月,龙智宣布已被评估为CMMI研究所的能力成熟度模型集成(CMMI)的 [3] 级. CMMI 是一个能力改进框架,它为组织提供有效流程的基本要素,最终提高其绩效. 成熟度级别 3 的评估 ...
- vue - vue基础/vue核心内容(终结篇)
今天是vue基础.vue核心内容第三天,也是最后一天,后面开始进入组件化学习,整个基础内容以生命周期的结束而结束,不得不说,张天禹把这节课讲活了,开始觉得vue是一个有生命的东西,包括前面所说的很多脏 ...
- 忘带U盘了??别急!一行python代码即可搞定文件传输
近日发现了python一个很有趣的功能,今天在这里给大伙儿做一下分享 需求前提 1.想要拷贝电脑的文件到另一台电脑但是又没有U盘2.手机上想获取到存储在电脑的文件3.忘带U盘- 您也太丢三落四了吧,但 ...