CF1461C 【Random Events】题解

首先,从后往前扫,找出第一个\(a_i\neq i\)的位置,记为\(st\)
从前往后扫,对于\(r_i<st\)的,选不选都没关系。
对于\(r_i\ge st\)的,至少有一个成功排序就会使整个序列被排序
考虑容斥,用所有情况减去\(r_i\ge st\)一个都不选的情况即可
即\(ans = 1-\prod\limits_{r_i\ge st} {1-p_i}\)
代码如下

#include <iostream>
#include <cstdio>
#include <cstring>
#include <cmath>
#include <cstdlib>
#include <vector>
#include <queue>
#include <algorithm>
using namespace std;
int t,n,m;
int a[100005],st;
inline int read() {
    int x=0,f=1;
    char ch=getchar();
    while(ch<'0'||ch>'9') {
        if(ch=='-')
            f=-1;
        ch=getchar();
    }
    while(ch>='0'&&ch<='9') {
        x=(x<<1)+(x<<3)+(ch^48);
        ch=getchar();
    }
    return x*f;
}
int r[100005];
double p[100005];
int main () {
	t = read();
	while(t--) {
		n = read();m = read();
		int flag = 1;
		for(int i = 1;i <= n;i++) a[i] = read();
		for(int i = 1;i <= m;i++) {
			scanf("%d%lf",&r[i],&p[i]);
		} 
		for(int i = 1;i <= n;i++) flag = flag & (a[i] == i);
		if(flag) {
			puts("1.00000000");
			continue;
		}
		for(int i = n;i >= 1;i--) {
			if(a[i] != i) {
				st = i;
				break;
			}
		}
		double ans = 1;
		for(int i = 1;i <= m;i++) {
			if(r[i] < st) continue;
			if(ans == 0) ans = 1-p[i];
			else ans = ans * (1-p[i]);
		}
		printf("%.10lf\n",1-ans);
	}
	return 0;
}
上一篇:破解已知函数单调性求参数范围的几个难点


下一篇:MindSpore技术理解(下)