列表

详情


NC19467. 期望操作数

描述

Nqijij 有一个数x,和一个神秘权值 q, 满足 x <= q, 每一次nqijij会随机x 变成 [x, q] 中的一个随机数,nqijij想要知道期望多少次操作之后x 变为q。
由于nqijij 是一个精力充沛的人,所以他总共会选择 T 次x 和q 进行操作,对于每一次操作,你需要输出期望多少次操作之后x 变为q 在 998244353 模意义下的值。
(令 ans = x / y, x, y 为正整数且 题目保证 x、y 与998244353 互质,则输出x * (y^(-1)), (y^(-1)) 表示y在998244353下的乘法逆元,可以证明这样的逆元存在)
题目保证 T <= 1e6, q <= 1e7, x <= 1e7;

输入描述

第一行一个数T
接下来T行
每行两个整数 x, q (x <= q)

输出描述

输出T行
第 i 行的正整数 表示第i次询问的答案。

示例1

输入:

2
7 8
15 18

输出:

2
831870297

说明:

对于第一个样例
每一次有0.5的概率结束利用简单的求和可知是2.

原站题解

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

C++14(g++5.4) 解法, 执行用时: 1104ms, 内存消耗: 166764K, 提交时间: 2018-09-28 21:14:38

#include<bits/stdc++.h>
using namespace std;
const int mod=998244353;
long long sum[10000007],inv[10000007];
int main() {
    sum[0]=-1;
    sum[1]=1;
    inv[1]=1;
	for(int i=2;i<=10000000;++i) {
        inv[i]=1ll*(mod-(mod/i))*inv[mod%i]%mod;
        sum[i]=sum[i-1]+inv[i];
		if(sum[i]>=mod) sum[i]-=mod;
	}
	int T,x,q;
	scanf("%d",&T);
	while(T--) {
		scanf("%d%d",&x,&q);
		printf("%lld\n",sum[q-x]==mod-1?0:sum[q-x]+1);
	}
	return 0;
}

C++11(clang++ 3.9) 解法, 执行用时: 817ms, 内存消耗: 53220K, 提交时间: 2018-09-28 20:33:03

#include<cstdio>
const int p=998244353;
const int N=11000000;
int inv[N],T,x,q;
int main(){
	scanf("%d",&T);inv[1]=inv[0]=1;
	for (int i=2;i<N;i++) inv[i]=(long long)((long long)(p-p/i)*(long long)inv[p%i])%p;
	for (int i=1;i<N;i++) inv[i]=(inv[i]+inv[i-1])%p;
	while (T--){
		scanf("%d%d",&x,&q);
		printf("%d\n",inv[q-x]);
	}
	return 0;
}

上一题