列表

详情


NC232414. gcd

描述

给出一个序列,长度为 n,其中每一项都是正整数。序列的第 ia_i 属于区间

求所有 种情况下 的约数个数和,对 998244353 取模。

输入描述

第一行一个正整数 n

接下来 n 行,第 i 行两个正整数 l_i,r_i

输出描述

输出一行一个正整数,为所有情况下  的约数个数和,对 998244353 取模。

示例1

输入:

4
1 4
1 5
3 6
4 10

输出:

598

示例2

输入:

4
38943 94594
23 46566
29384 48372
1 3990

输出:

173742882

原站题解

上次编辑到这里,代码来自缓存 点击恢复默认模板

C++ 解法, 执行用时: 2468ms, 内存消耗: 6300K, 提交时间: 2022-01-21 15:15:55

#include<bits/stdc++.h>
#define ll long long
using namespace std;
const ll mod=998244353;
const int maxn=3e5+10;
ll c[maxn],inv[maxn];
int c0[maxn];
int main(){
	for(int i=0;i<=3e5;i++)c[i]=1;
	memset(c0,0,sizeof(c0));inv[1]=1;
	for(int i=2;i<=3e5;i++)inv[i]=(mod-mod/i)*inv[mod%i]%mod;
	int l,r,n;cin>>n;
	for(int i=1;i<=n;i++){
		cin>>l>>r;l--;
		c0[r+1]++;
		for(int j=1,k;j<=r;j=k+1){
			int x=r/j,y=l/j;
			if(y==0)k=r/x;
			else k=min(r/x,l/y);
			int u=x-y;
			if(u==0)c0[j]++,c0[k+1]--;
			else c[j]=c[j]*u%mod,c[k+1]=c[k+1]*inv[u]%mod;
		}
	}
	ll ans=0;
	for(int i=1;i<=3e5;i++){
		c[i]=c[i]*c[i-1]%mod;
		c0[i]+=c0[i-1];
		if(!c0[i])ans=(ans+c[i])%mod;
	}
	cout<<ans<<endl;
} 

上一题