题目链接

https://vjudge.net/contest/413174#problem/C

解题思路

思维吧。
是不是有人没看懂题QWQ,看我题解,会讲解一个样例
大致思路:
从后往前找到第一个不符合自己位置的数现在所在的位置。
对于每一次实验,若输入的数比记录的位置小,是否改成有序,都无所谓,因为要想整个序列变得有序,必须要把无序的部分一次性改完才行;否则,这次实验可以把序列变得有序,为了方便解释,我们拿题目给的第三个样例讲解一下,很显然,这个序列前三个的顺序错了,所以小于3的改不改无所谓,我们完全可以忽略(2,0.4)这组实验,进行第一次实验(4,0.9),修改成功的概论为0.9,所以ans+=0.9;第二次实验(5,0.3),修改成功的概论为 “第一次失败且第二次成功” 的概论 + “第一次成功” 的概论,但是 “第一次成功” 的概论我们加过了,所以只用加上 “第一次失败且第二次成功” 的概论,即0.1 * 0.3,ans+=0.03;第三次实验pass,本质为ans乘1;第四次实验(6,0.7),只需要加上, “第一次失败且第二次失败且第四次成功” 的概论;……。完全归纳能得到,每次ans要加上的概论为前i-1次有效实验都失败的概论 * 第i次成功的概论。
注意特殊情况的判断,当序列已经排好序的时候,直接输出1。

AC代码

#include<bits/stdc++.h>
using namespace std;
const int N=1e5+100;
int main()
{
    int t,a[N],pos,n,m;
    cin>>t;
    while(t--)
    {
        memset(a,0,sizeof a);pos=0;
        cin>>n>>m;
        for(int i=1;i<=n;i++) cin>>a[i];
        for(int i=n;i>=1;i--) if(a[i]!=i) {pos=i;break;}
        double ppp=1,pp=0,p,ans=0;
        int x;
        while(m--)
        {
            cin>>x>>p;
            if(x<pos) continue;
            ans+=ppp*(1-pp)*p;
            ppp*=(1-pp);
            pp=p;            
        }
        if(pos) cout<<ans<<endl;
        else puts("1.0");
    }    
    return 0;
}

总结

半小时A掉,比b题做得还快……
感觉还是cf的样例人性化,样例给的多,而且特殊情况有时候也能给点,牛牛能不能向cf学习一下啊,别封我号啊QWQ