• Codeforces 1264C Beautiful Mirrors with queries(逆元,递推,概率期望)


    思路:

    这道题应该是1265E1265EHardVersionHard Version,根据1265E Beautiful Mirrors该题的题解,我们可以得到dp[i]=dp[i-1]+pi*1+(1-pi)*(dp[i]+1)的递推式;(稍微变换一下就可以得到dp[i]的递推式)
    稍微理解一下题意,我们就可以知道,每次查询,我们用这些分割点将区间n分割开来,单独求期望,最后相加即可;
    此题我们设E(i,j)为通过[i,j]所有镜子的期望天数,类似的我们可以得到E(i,j)=(E(i,j-1)+1)/pj,将E(i,j-1)再展开,然后将迭代出的式子再展开,最终我们可以得到
    E(i,j)=1+pi+pipi+1+...+pipi+1...pj1pipi+1...pjE(i,j)=frac{1+p_{i}+p_{i}p_{i+1}+...+p_{i}p_{i+1}...p_{j-1}}{p_{i}p_{i+1}...p_{j}}
    设前缀积数组mul[i]=p1*p2*p3*...*pi,分母就很好求了,为mul[j]/mul[i-1]
    设前缀和数组sum=p1+p1*p2+...+p1*p2*...pi,那分母就是1+(sum[j-1]-sum[i-1])/mul[i-1]
    然后合起来写再通个分就可以求得E(i,j)了;
    每次查询,我们只需要做小小的变化,就能在O(logn)O(logn)的时间修改答案(具体看代码)
    我们这里的pi是概率,题目给的pi/100才是概率,我们用100的逆元乘上pi即可;

    代码:

    #include<bits/stdc++.h>
    using namespace std;
    #define pt(a) cerr<<a<<"---
    "
    typedef long long LL;
    const LL M=998244353;
    void extgcd(LL a,LL b,LL& x,LL& y){
        if(b==0){x=1,y=0;return;}
        extgcd(b,a%b,x,y);
        LL t=x;x=y;y=t-(a/b)*y;
    }
    LL mod_inv(LL a){LL x,y;extgcd(a,M,x,y);return (M+x%M)%M;}
    const int maxn=2e5+99;
    int n,q;
    LL res=0,mul[maxn],sum[maxn],p[maxn];
    set<int> st;
    #define E(i,j) ((mul[i-1]+sum[j-1]-sum[i-1]+M)%M*mod_inv(mul[j])%M)
    void init_(){
        mul[0]=1;
        for(int i=1;i<=n;i++)mul[i]=mul[i-1]*p[i]%M;
        for(int i=1;i<=n;i++)sum[i]=(sum[i-1]+mul[i])%M;
        st.insert(1);st.insert(n+1);
        res=E(1,n);
    }
    int u;
    void solve(){
        if(st.count(u)){
            auto it=st.find(u);
            auto pit=it,qit=it;pit--;qit++;
            res-=E(*pit,*it-1)+E(*it,*qit-1);
            res+=E(*pit,*qit-1);
            st.erase(u);
        }else{
            auto it=st.insert(u).first;
            auto pit=it,qit=it;pit--;qit++;
            res-=E(*pit,*qit-1);
            res+=E(*pit,*it-1)+E(*it,*qit-1);
        }
        res%=M;
        if(res<0)res+=M;
        cout<<res<<'
    ';
    }
    int main(){
    	ios::sync_with_stdio(false);
    	cin.tie(nullptr);
        cin>>n>>q;
        LL x=mod_inv(100);
        for(int i=1;i<=n;i++)cin>>p[i],p[i]=p[i]*x%M;
        init_();
        for(int i=0;i<q;i++){
            cin>>u;
            solve();
        }
    	return 0;
    }
    
    
  • 相关阅读:
    【LeetCode每日一题】2020.6.9 面试题46. 把数字翻译成字符串
    【NOIP2017提高A组模拟9.17】信仰是为了虚无之人
    【NOIP2017提高A组模拟9.17】猫
    【NOIP2017提高A组模拟9.17】组合数问题
    JZOJ 11.21 提高B组反思
    【NOIP2017提高A组模拟9.12】Arrays and Palindrome
    JZOJ【NOIP2013模拟联考14】隐藏指令
    JZOJ 11.14 提高B组反思
    CSP2020复赛游记
    JZOJ 【NOIP2017提高A组模拟9.14】捕老鼠
  • 原文地址:https://www.cnblogs.com/yuhan-blog/p/12308757.html
Copyright © 2020-2023  润新知