CF1461 C. Random Events
题目大意:
给定一个长为n的序列,m个询问,每次询问两个数第一个为从1开始所到右边界,第二个数为一个概率,代表着将这一段数组变为升序的可能性。问最后将整个数组变为非降序的概率。
思路:
首先要对询问进行分析,何时的操作为有效操作,若我们所修改的区间内为整个数组与非递减序不符的所有部分时才为我们所进行的有效操作范围,所以我们只需要从后往前遍历,找到最后一个与答案不同的地方,打上标记。如果我们所询问的数大于等于这个数,那我们就进行操作。
对于每次操作的概率我们只需累乘其失败概率最后用一减去即可,
#define _CRT_SECURE_NO_WARNINGS
#include<iostream>
#include<algorithm>
#include<cstring>
#include<string>
#include<map>
#include<cstdio>
#include<cmath>
#include<iomanip>
#include<sstream>
#include<queue>
#define pi 3.1415926535
#define me(a,b,c) memset(a,b,sizeof c)
#define eps 0.00000001
//#define x first
//#define y second
using namespace std;
typedef long long ll;
const int mod = 1e9 + 7;
typedef pair<int, int> pii;
const int N = 1e6+10;
int a[N];
int b[N];
int main()
{
int t;
cin >> t;
while (t--)
{
int n, m;
cin >> n >> m;
for (int i = 1; i <= n; i++) {
cin >> a[i];
b[i] = a[i];
}
int pos = 0;
sort(b + 1, b + 1 + n);
for (int i = n; i >= 1; i--) {
if (a[i] != b[i]) {
pos = i;
break;
}
}
double ans = 1;
while (m--)
{
int r;
double p;
cin >> r >> p;
if (r >= pos) {
ans *=(1.0-p);
}
}
if (!pos) {
printf("%.8lf\n", 1.0);
continue;
}
printf("%.8lf\n",1- ans);
}
}
//
//Buddha blesses the code with no bugs
// _ooOoo_
// o8888888o
// 88" . "88
// (| -_- |)
// O\ = /O
// ____/`---'\____
// .' \| |// `.
// / \||| : |||// \
// / _||||| -:- |||||- \
// | | \\ - /// | |
// | \_| ''\---/'' | |
// \ .-\__ `-` ___/-. /
// ___`. .' /--.--\ `. . __
// ."" '< `.___\_<|>_/___.' >'"".
// | | : `- \`.;`\ _ /`;.`/ - ` : | |
// \ \ `-. \_ __\ /__ _/ .-` / /
// ======`-.____`-.___\_____/___.-`____.-'======
// `=---='
// ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
//