zoukankan      html  css  js  c++  java
  • 2020牛客暑期多校训练营(第九场)C

    Description

    给定 (n) 个区间,每个区间有 (1/2) 的概率被选中,求区间交的长度的平方的期望。

    Solution

    要求区间交的长度的平方的期望,就是要求所有选择方案的区间交集长度平方的和,将平方拆掉,即枚举每个小段算它的贡献,这个贡献即这个小段的长度乘以限制这个小段选中时,所有方案的区间交长度的和。为了求后者,定义覆盖了刚才枚举的小段的所有线段为当前存在的线段,那么我们再次枚举所有小段,每个小段的贡献就是它的长度乘以包含它的方案数,设后面枚举的这个小段被所有当前存在的线段覆盖的次数为 (x),则这个方案数为 (2^x-1)

    于是最终我们要求的东西可以被写成这样的形式

    [sum_{i} |P_i| sum_{j} frac{2^{f(i,j)}-1} {2^n} |P_j| ]

    其中 (f(i,j)) 表示所有覆盖了小段 (i) 的线段覆盖小段 (j) 的次数。

    实际求解时,先将 (-1) 项提出来,其和就等于数轴长度平方除以 (2^n),前面的部分,(i) 暴力枚举,(j) 用线段树维护一下即可。

    #include <bits/stdc++.h>
    using namespace std;
    
    #define int long long 
    const int N = 1000005;
    const int mod = 998244353;
    const int inv2 = (mod+1)/2;
    const int oo = 1e9+1;
    
    map <int,int> mp;
    int sum[N*4],tag[N*4],breakpoint[N],n,ind,ans,len;
    
    void change(int p,int v)
    {
        sum[p]=(sum[p]*v)%mod;
        tag[p]=(tag[p]*v)%mod;
    }
    
    void pushup(int p)
    {
        sum[p]=(sum[p*2]+sum[p*2+1])%mod;
        tag[p]=1;
    }
    
    void pushdown(int p)
    {
        if(tag[p]!=1)
        {
            change(p*2,tag[p]);
            change(p*2+1,tag[p]);
            tag[p]=1;
        }
    }
    
    void build(int p,int l,int r)
    {
        if(l==r)
        {
            sum[p]=breakpoint[l+1]-breakpoint[l];
            tag[p]=1;
        }
        else
        {
            build(p*2,l,(l+r)/2);
            build(p*2+1,(l+r)/2+1,r);
            pushup(p);
        }
    }
    
    void modify(int p,int l,int r,int ql,int qr,int v)
    {
        if(l>qr || r<ql) return;
        if(l>=ql && r<=qr)
        {
            change(p,v);
        }
        else
        {
            pushdown(p);
            modify(p*2,l,(l+r)/2,ql,qr,v);
            modify(p*2+1,(l+r)/2+1,r,ql,qr,v);
            pushup(p);
        }
    }
    
    int query(int p,int l,int r,int ql,int qr)
    {
        if(l>qr || r<ql) return 0;
        if(l>=ql && r<=qr)
        {
            return sum[p];
        }
        else
        {
            pushdown(p);
            return (query(p*2,l,(l+r)/2,ql,qr)+query(p*2+1,(l+r)/2+1,r,ql,qr))%mod;
        }
    }
    
    struct Range 
    {
        int l,r;
    } range[N];
    
    struct Operation
    {
        int l,r,val;
    }; 
    
    vector <Operation> vecOperation[N];
    
    signed main()
    {
        ios::sync_with_stdio(false);
    
        mp[0]++;
        mp[oo]++;
    
        cin>>n;
        for(int i=1;i<=n;i++) 
        {
            cin>>range[i].l>>range[i].r;
            ++range[i].r;
            len+=range[i].r-range[i].l;
            mp[range[i].l]++;
            mp[range[i].r]++;
        }
    
        for(auto it=mp.begin();it!=mp.end();it++) it->second=++ind, breakpoint[ind]=it->first;
        breakpoint[ind+1]=breakpoint[ind];
        for(int i=1;i<=n;i++) range[i].l=mp[range[i].l], range[i].r=mp[range[i].r];
        build(1,1,ind);
    
        for(int i=1;i<=n;i++) 
        {
            vecOperation[range[i].l].push_back({range[i].l,range[i].r,2});
            vecOperation[range[i].r].push_back({range[i].l,range[i].r,inv2});
        }
    
        for(int i=1;i<=ind;i++)
        {
            for(auto op:vecOperation[i])
            {
                modify(1,1,ind,op.l,op.r-1,op.val);
            }
            ans+=sum[1]*(breakpoint[i+1]-breakpoint[i])%mod;
            ans%=mod;
        }
    
        ans-=oo*oo%mod;
        ans%=mod;
        ans+=mod;
        ans%=mod;
    
        for(int i=1;i<=n;i++) ans=(ans*inv2)%mod;
        cout<<ans<<endl;
    
        return 0;
    }
    
  • 相关阅读:
    VLAN
    Debug出错 Release没问题
    弹出VIEW.非dialog
    [转帖]Android Bitmap内存限制OOM,Out Of Memory
    关于性格内向者的10个误解,献给奋战在一线的程序员
    Android 调用webservice
    Android2.2新特性.APK安装参数installLocation
    数据结构中的基本排序算法总结
    Post Operation for Windows 8 Apps || Windows Phone
    ZipArchive For Windows 8 Apps
  • 原文地址:https://www.cnblogs.com/mollnn/p/13798955.html
Copyright © 2011-2022 走看看