zoukankan      html  css  js  c++  java
  • [cf 1264 C] Beautiful Mirrors with queries

    题意:

    你有$n$个魔镜,第$i$个魔镜有$p_{i}$的概率说你美。

    从第1天开始,你会依次询问魔镜$1-n$你美不美。

    若第$i$个魔镜说你美则你明天会继续询问第$i+1$个魔镜。

    否则你明天会从该魔镜前面第一个复活点魔镜开始询问。初始时只有魔镜1是复活点。

    当第$n$个魔镜说你美的时候你会开心的一批。

    现在有$q$次操作,每次操作修改一个魔镜使其成为/不成为复活点。

    每次操作之后请你求出期望多少天你能开心的一批。

    $n,qleq 2 imes 10^{5}$。

    题解:推出一段区间答案的简单表示形式即可。

    一开始想复杂了,用期望的线性性推了个式子发现做不了。

    实际上我们只需要根据最简单的思路推式子即可。

    设$E_{i}$为从$i$走到$n$的期望天数。

    则有$E_{i}=p_{i} imes(1+E_{i+1})+(1-p_{i}) imes(1+E_{1})$。

    手动消元一下$E_{1}$,得到$E_{1}=frac{1}{p_{n}}+frac{1}{p_{n}p_{n-1}}+cdots +frac{1}{p_{n}p_{n-1}cdots p_{1}}$。

    那么考虑复活点这件事,容易发现整个序列被复活点分成了若干个区间。

    每个区间是独立的。即$ans=sum{E_{[f_{i-1},f_{i}]}}$。

    那么我们考虑$E_{[l,r]}$如何计算。

    推广上面那个式子,得到$E_{[l,r]}=frac{1}{p_{r}}+frac{1}{p_{r}p_{r-1}}+cdots +frac{1}{p_{r}p_{r-1}cdots p_{l}}$。

    我们设$s_{i}$为$p_{1}p_{2}cdots p_{i}$,那么有

    $E_{[l,r]}=frac{(p_{r-1}p_{r-2}cdots p_{l}+p_{r-2}p_{r-3}cdots p_{l}+cdots +p_{l}+1)}{frac{s_{r}}{s_{l-1}}}$。

    我们再设$ss_{i}=s_{1}+s_{2}+cdots +s_{i}$,那么有

    $E_{[l,r]}=frac{frac{(ss_{r-1}-ss_{l-1})}{s_{l-1}}+1}{frac{s_{r}}{s_{l-1}}}$。

    于是只需要用一个$set$维护复活点即可做到$O(nlogn)$。

    代码:

    #include<bits/stdc++.h>
    #define maxn 200005
    #define maxm 500005
    #define inf 0x7fffffff
    #define mod 998244353
    #define ll long long
    #define debug(x) cerr<<#x<<": "<<x<<endl
    #define fgx cerr<<"--------------"<<endl
    #define dgx cerr<<"=============="<<endl
     
    using namespace std;
    ll s[maxn],ss[maxn];
    set<int> st;
     
    inline ll read(){
        ll x=0,f=1; char c=getchar();
        for(;!isdigit(c);c=getchar()) if(c=='-') f=-1;
        for(;isdigit(c);c=getchar()) x=x*10+c-'0';
        return x*f;
    }
     
    inline ll power(ll a,ll b){ll ans=1;while(b) ans=(b&1)?ans*a%mod:ans,a=a*a%mod,b>>=1;return ans;}
    inline ll inv(ll x){return power(x,mod-2);}
    inline ll mo(ll x){return x>=mod?x-mod:x;}
    inline ll calc(ll l,ll r){return (mo(ss[r-1]-ss[l-1]+mod)*inv(s[l-1])%mod+1)*inv(s[r]*inv(s[l-1])%mod)%mod;}
     
    int main(){
        ll n=read(),q=read(); s[0]=1;
        for(ll i=1;i<=n;i++){
            ll x=read()*inv(100)%mod;
            s[i]=s[i-1]*x%mod,ss[i]=(ss[i-1]+s[i])%mod;
        }
        st.insert(1),st.insert(n+1);
        ll ans=(ss[n-1]+1)%mod*inv(s[n])%mod;
        while(q--){
            int x=read();
            set<int>::iterator it=st.lower_bound(x);
            if(*it==x){
                int l=*(--it);it++;int r=(*(++it));//cout<<1<<":"<<l<<" "<<r<<endl;
                ans=mo(ans-calc(l,x-1)+mod),ans=mo(ans-calc(x,r-1)+mod),ans=mo(ans+calc(l,r-1)),st.erase(x);
            }
            else{
                int l=*(--it);it++;int r=(*it);//cout<<2<<":"<<l<<" "<<r<<endl;
                ans=mo(ans-calc(l,r-1)+mod),ans=mo(ans+calc(l,x-1)),ans=mo(ans+calc(x,r-1)),st.insert(x);
            }
            printf("%I64d
    ",ans);
        }
        return 0;
    }
    C
  • 相关阅读:
    java——对象学习笔记
    ORACLE中如何查看分区表信息
    postgresql相关系统表查询
    oracle系统表查询
    linux shell常用函数,ps
    文本文件合并
    nginx多版本PHP配置
    webuploader实现文件上传
    open abc.txt: The system cannot find the file specified
    PHP在线批量下载文件
  • 原文地址:https://www.cnblogs.com/YSFAC/p/12003135.html
Copyright © 2011-2022 走看看