[Wannafly挑战赛25 ] A B C[概率DP]

版权声明:将来的你一定会感谢现在努力的你!!!! https://blog.csdn.net/qq_37383726/article/details/82924187

A
链接:https://www.nowcoder.com/acm/contest/197/A
来源:牛客网

时间限制:C/C++ 1秒,其他语言2秒
空间限制:C/C++ 262144K,其他语言524288K
64bit IO Format: %lld
题目描述
令 X = n!, 给定一大于1的正整数p 求一个k使得 p ^k | X 并且 p ^(k + 1) 不是X的因子。
输入描述:
两个数n, p (1e18>= n>= 10000 >= p >= 2)
输出描述:
一个数
表示k
示例1
输入
10000 12
输出
4996
分析: 用算数基本定理考虑
p = p 1 r 1 p 2 r 2 p 3 r 3 . . . p n r n p = p_1^{r_1} * p_2 ^ {r_2} * p_3 ^ {r_3} *... * p_n^{r_n}
X = p 1 m 1 p 2 m 2 p 3 m 3 . . . p n m n X = p_1^{m_1} * p_2 ^ {m_2} * p_3 ^ {m_3} *... * p_n^{m_n}
由题意可知, p k p^k 要是 X X 的因子, 所以对于所有的 i i 一定有 r i k = m i r_i * k = m_i 所以 a n s = m i n ( m i r i ) ans = min(\frac{m_i} {r_i})
Code

 
#include <bits/stdc++.h>
#include <iostream>
#include <stdio.h>
#include <string.h>
#include <algorithm>
#include <string>
#include <math.h>
#include <stack>
#include <vector>
#include <queue>
#include <set>
#include <map>
using namespace std;
#define rep(i, l, r) for(unsigned int i = l; i < r; i++)
#define per(i, r, l) for(unsigned int i = r; i >= l; i--)

typedef long long ll;
typedef unsigned long long ull;
typedef pair<int, int>pii;

const int N = (int) 1e5 + 11;
const int M = (int) 1e6 + 11;
const int MOD = (int) 1e9 + 7;
const int INF = (int) 0x3f3f3f3f;
const ll INFF = (ll) 0x3f3f3f3f3f3f3f3f;
/*-----------------------------------------------------------*/
int main(){
	
    ll n, p;
	cin >> n >> p;	
	ll ans = 1ll << 60;	
	for(int i = 2; i * i <= p; i ++){
		if(p % i == 0) {
			int cnt = 0;
			while(p % i == 0) {
				cnt ++;
				p /= i;
			}	
			ll nn = n;	
			ll cc = 0;
			while(nn){
				cc += nn / i;
				nn /= i;
			}	
			ans = min(ans, cc / cnt);
		}
	}
	if(p > 1){
		ll nn = n;	
		ll cc = 0;
		while(nn){
			cc += nn / p;
			nn /= p;
		}	
		ans = min(ans, cc);
	}
	cout << ans <<"\n";
    return 0;
}

B
链接:https://www.nowcoder.com/acm/contest/197/B
来源:牛客网

时间限制:C/C++ 1秒,其他语言2秒
空间限制:C/C++ 131072K,其他语言262144K
64bit IO Format: %lld
题目描述
cxt有一个正n边形,它的外接圆的圆心位于原点,半径为l。以原点为圆心,r为半径作一个圆,求圆和这个正n边形的面积并。
输入描述:
输入三个整数n,l,r。
3<=n<=100000000
1<=l<=1000000
0<=r<=1000000
输出描述:
输出一个实数,保留2位小数,表示面积并。
示例1
输入
8 7 6
输出
138.59
分析: 简单几何,自己画图算算就好,一共三种情况.
Code
注意要开long double不然精度好像不够.

 
#include <bits/stdc++.h>
#include <iostream>
#include <stdio.h>
#include <string.h>
#include <algorithm>
#include <string>
#include <math.h>
#include <stack>
#include <vector>
#include <queue>
#include <set>
#include <map>
using namespace std;
#define rep(i, l, r) for(unsigned int i = l; i < r; i++)
#define per(i, r, l) for(unsigned int i = r; i >= l; i--)
#define double long double 

typedef long long ll;
typedef unsigned long long ull;
typedef pair<int, int>pii;

const int N = (int) 1e5 + 11;
const int M = (int) 1e6 + 11;
const int MOD = (int) 1e9 + 7;
const int INF = (int) 0x3f3f3f3f;
const double PI = (double)acos(-1.0);
const ll INFF = (ll) 0x3f3f3f3f3f3f3f3f;
/*-----------------------------------------------------------*/

int main(){
	double n, l, r; cin >> n >> l >> r;
	double du = PI / n;
	double h = cos(du) * l;
	double minji_duo = l * h * sin(du) * n;
	double minji_circle = PI * r * r;
	double ans;
	if(r > h && r < l) {
		double dd = acos(h / r);
		double tt = h * r * sin(dd);
		double t = dd * r * r; 
		ans = minji_duo + n * (t - tt);
	} else if(r <= h) {
		ans = minji_duo;
	} else if(r >= l) {
		ans = minji_circle;
	}
	printf("%.2Lf\n", ans);
    return 0;
}

C
链接:https://www.nowcoder.com/acm/contest/197/C
来源:牛客网

时间限制:C/C++ 2秒,其他语言4秒
空间限制:C/C++ 262144K,其他语言524288K
64bit IO Format: %lld
题目描述
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.

分析: 简单思考,我们应该可以得出,这个操作数的期望是只和长度有关的.故我们可以打表求出所有长度的解,对于每组测试数据直接输出即可.然后我们考虑DP, d p i dp_i 表示长度为 i i 的操作数的期望为多少.

我们提前处理o(n)逆元筛一下,就可以做到o(n)了;
Code

 
#include <iostream>
#include <stdio.h>
#include <string.h>
#include <algorithm>
#include <string>
#include <math.h>
#include <stack>
#include <vector>
#include <queue>
#include <set>
#include <map>
using namespace std;
#define rep(i, l, r) for(unsigned int i = l; i < r; i++)
#define per(i, r, l) for(unsigned int i = r; i >= l; i--)

typedef long long ll;
typedef unsigned long long ull;
typedef pair<int, int>pii;

const int N = (int) 1e7 + 11;
const int M = (int) 1e6 + 11;
const int MOD = (int) 998244353;
const int INF = (int) 0x3f3f3f3f;
const ll INFF = (ll) 0x3f3f3f3f3f3f3f3f;
/*-----------------------------------------------------------*/

int inv[N];
int dp[N];
int main(){
	inv[1] = 1;
	for (int i = 2; i<N; i++)
		inv[i] = 1ll*inv[MOD%i]*(MOD-MOD/i)%MOD;
	dp[1] = 0;
	ll sum = 0;
	for(int i = 2; i < N; i++){
		dp[i] = ( inv[i] * sum % MOD + 1 ) * i % MOD * inv[i - 1] % MOD ;
		sum =( sum + dp[i] ) % MOD; 	
	}
//	rep(i, 1, 10) printf("%d ", dp[i]); 
	int T; scanf("%d" ,&T);
	while(T--){
		int x, q; scanf("%d%d", &x ,&q);
		printf("%d\n", dp[q - x + 1]);
	}
	return 0;
}

猜你喜欢

转载自blog.csdn.net/qq_37383726/article/details/82924187