列表

详情


NC16031. 小球碰撞

描述

一个弹球(可视为质点)被水平抛出,落地时发生完全弹性碰撞,设弹球第一次落地位置为x,则第i次落地位置为(2i-1)x
若弹球第一次落地的位置在区间[L,R]均匀随机分布,求弹球落在区间[L,R]内的总次数的数学期望值 

可以证明答案为有理数,若答案表示为最简分数为a/b,则存在c使得b*c mod 998244353 = 1 ,只需输出a*c mod 998244353

输入描述

第一行,一个整数n
接下来n行,每行两个空格分隔的整数L,R

输出描述

输出n行,每行一个整数,表示a*c mod 998244353

示例1

输入:

3
3 4
3 5
1 5

输出:

1
1
166374060

原站题解

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

C++14(g++5.4) 解法, 执行用时: 616ms, 内存消耗: 157432K, 提交时间: 2019-08-06 11:43:55

#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
int const mod = 998244353;
int const N = 1e7 + 10;
ll l,r;
ll inv[N],sum[N];
void init(){
	inv[1] = 1,	sum[1] = 1;
	for(int i=2;i<N;i++){
		inv[i] = inv[mod % i] * (mod - mod / i) % mod;
		sum[i] = (sum[i-2] + inv[i]) % mod;
	}
}
int main(){
	init();
	int T;
	scanf("%d",&T);
	while(T--){
		scanf("%lld%lld",&l,&r);
		int k = (r / l + 1) / 2;
		ll ans = sum[2 * k - 1] - l * inv[r] % mod * k % mod;
		ans %= mod;
		ans = ans * r % mod * inv[r - l] % mod;
		ans = (ans % mod + mod) % mod;
		printf("%lld\n",ans);
	}
	return 0;
}

C++(clang++ 11.0.1) 解法, 执行用时: 200ms, 内存消耗: 79116K, 提交时间: 2022-08-11 10:16:39

#include<bits/stdc++.h>
using namespace std;
#define ll long long
#define P 998244353
int a[20000005],b[20000005],i,l,r,n,t;
int main()
{
	for(a[1]=1,i=2;i<10000005;i++)a[i]=(ll)(P-P/i)*a[P%i]%P;
	for(i=1;i<10000005;i++)
	{
		b[i]=b[i-1]+a[i];
		if(b[i]>=P)b[i]-=P;
	}
	scanf("%d",&t);
	while(t--)
	{
		scanf("%d%d",&l,&r);
		n=(r+l)/l>>1;
		printf("%d\n",(r*(b[n<<1]+(ll)(P-1>>1)*b[n]%P)%P-(ll)l*n%P+P)*a[r-l]%P);
	}
	return 0;
}

上一题