• NOIP2023模拟13联测34 competition


    题目大意

    给定一个有 n n n个选手的团队去参加比赛,比赛有 m m m道题,每个选手可以 100 % 100\% 100%将第 l i ∼ r i l_i \sim r_i liri道题做出来。

    比赛时,团队会随机派出编号连续的人去做题,得分为做出来题目的总数。

    求该团队参加比赛的期望得分。

    答案对 1 e 9 + 7 1e9+7 1e9+7取模。

    题目思路

    我们先考虑暴力做法,先 n 2 n^2 n2枚举派出那些选手去参加比赛,然后 log ⁡ n \log n logn算出他们一共能做出多少道题,最后答案就是所有可能做出来的题目数量乘上 n ∗ ( n + 1 ) 2 \frac{n*(n+1)}{2} 2n(n+1)在模意义下的逆元即可。

    现在考虑正解。

    我们可以将枚举区间改为计算每道题对答案的贡献。

    l s t j lst_j lstj记录的是 i i i前面第一个可以做出来 j j j的人。

    一开始假设每道题都会被包含在任意区间,然后顺序枚举 i i i,对于 l i ∼ r i l_i \sim r_i liri中的每个 j j j,我们设 l s t j lst_j lstj表示 i i i前面第一个可以做出这道题的人,因为 ( l s t j , i ) (lst_j,i) (lstj,i)中的区间不包含 j j j,所以 j j j不会对这个区间中的任意区间做贡献,答案就应该减去 ( i − l s t j ) ∗ ( i − l s t j − 1 ) 2 \frac{(i-lst_j)*(i-lst_j-1)}{2} 2(ilstj)(ilstj1)

    考虑怎么维护 l s t j lst_j lstj,一开始 l s t j lst_j lstj全为 0 0 0,每次操作后都会将 l s t lst lst数组中 l i ∼ r i l_i \sim r_i liri赋值为 i i i,所以 l s t lst lst可以用柯朵莉树维护。

    最后在乘上方案数的逆元即可。

    具体实现参考代码。

    #include
    using namespace std;
    long long n,m,ans=0;
    const long long mod=1e9+7,inv=5e8+4;
    struct node
    {
        long long l,r;
        mutable long long v;
        node(long long L,long long R=-1,long long V=0)
        {
            l=L,r=R,v=V;
        }
        bool operator<(const node &a) const
        {
            return l<a.l;
        }
    };
    set<node> a;
    long long read()
    {
        long long s=0,w=1;
        char ch=getchar();
        while(ch<'0'||ch>'9')
        {
            if(ch=='-')
                w=-1;
            ch=getchar();
        }
        while(ch>='0'&&ch<='9')
            s=s*10+(ch-'0'),ch=getchar();
        return s*w;
    }
    auto split(long long pos)
    {
        auto it=a.lower_bound(pos);
        if(it!=a.end()&&it->l==pos)
            return it;
        it--;
        long long l=it->l;
        long long r=it->r;
        long long v=it->v;
        a.erase(it);
        a.insert(node(l,pos-1,v));
        return a.insert(node(pos,r,v)).first;
    }
    void emerge(long long l,long long r,long long k)
    {
        auto itr=split(r+1);
        auto itl=split(l);
        for(auto it=itl;it!=itr;++it)
            ans=(ans-(it->r-it->l+1)*(k-it->v)%mod*(k-it->v-1)%mod*inv%mod+mod)%mod;
        a.erase(itl,itr);
        a.insert(node(l,r,k));
        return ;
    }
    long long ksm(long long a,long long b)
    {
        long long sum=1;
        while(b)
        {
            if(b&1)
                sum=sum*a%mod;
            a=a*a%mod;
            b>>=1;
        }
        return sum;
    }
    int main()
    {
        freopen("competition.in","r",stdin);
        freopen("competition.out","w",stdout);
        n=read(),m=read();
        a.insert(node(1,m+10,0));
        ans=m%mod*n%mod*(n+1)%mod*inv%mod;
        for(int i=1;i<=n;++i)
        {
            long long l=read(),r=read();
            emerge(l,r,i);
        }
        emerge(1,m,n+1);
        ans=ans*ksm(n*(n+1)%mod*inv%mod,mod-2)%mod;
        printf("%lld",ans);
        return 0;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66
    • 67
    • 68
    • 69
    • 70
    • 71
    • 72
    • 73
    • 74
    • 75
    • 76
    • 77
    • 78
    • 79
    • 80
    • 81
    • 82
    • 83
    • 84
  • 相关阅读:
    如何创建与引擎独立的Iceberg表
    计算机对字节的七种操作
    CAD二次开发(9)- CAD中对象的实时选择
    apollo配置中心
    7-4 USB接口的定义 (10分)
    数据结构练级之路【链表带环问题】
    科技云报道:押注向量数据库,为时过早?
    短视频时代,亚马逊产品视频的作用是什么?对于提升Listing转化率究竟有何好处?
    学习心得09:C++新特性
    变电站指针式仪表示数识别方法研究
  • 原文地址:https://blog.csdn.net/qq_62668011/article/details/134316757