• [luogu3600]随机数生成器


    令$P(k)$表示最小值的最大值小于等于$k$的概率,答案即为$sum_{i=1}^{x}(P(i)-P(i-1))i=x-sum_{i=1}^{x-1}P(i)$(其中利用到$P(x)=1$且$P(0)=0$)

    $P(k)$的意义就是让每一个区间内都有一个小于等于$k$的数,考虑如何求出这个概率:

    对于相互包含的区间,显然可以删掉较大的区间,再将剩下的区间排序后左右端点分别单调递增

    假设剩下的区间依次为$[l_{1},r_{1}],[l_{2},r_{2}],...,[l_{q},r_{q}]$,令$f_{i}$表示仅考虑$r_{i}$以前,覆盖了前$i$个区间的概率,那么枚举最后一个位置$j$,令$j'=max_{r_{k}<j}k$,则$f_{i}=frac{x}{k}sum_{j=l_{i}}^{r_{i}}(1-frac{k}{x})^{r_{i}-j}f_{j'}$

    首先将$(1-frac{k}{x})^{r_{i}-j}$拆为$(1-frac{k}{x})^{r_{i}}$和$(1-frac{k}{x})^{-j}$,前者可以提到求和外面,后者仅与$j$有关,可以看作每一次求出$f_{i}$,就将$(r_{i},n]$用$f_{i}$区间覆盖,之后每一个点还有一个系数,要求区间求和,线段树即可维护

    总复杂度为$o(mqlog_{2}n)$,可以通过

     1 #include<bits/stdc++.h>
     2 using namespace std;
     3 #define N 2005
     4 #define mod 666623333
     5 #define L (k<<1)
     6 #define R (L+1)
     7 #define mid (l+r>>1)
     8 struct ji{
     9     int l,r;
    10 }a[N];
    11 int n,m,q,ans,st[N],vis[N],lst[N],f[N],tag[N<<2],val[N<<2],sum[N<<2];
    12 bool cmp(ji x,ji y){
    13     return (x.l<y.l)||(x.l==y.l)&&(x.r>y.r);
    14 }
    15 int ksm(int n,int m){
    16     int s=n,ans=1;
    17     while (m){
    18         if (m&1)ans=1LL*ans*s%mod;
    19         s=1LL*s*s%mod;
    20         m>>=1;
    21     }
    22     return ans;
    23 }
    24 void upd(int k,int x){
    25     tag[k]=x;
    26     sum[k]=1LL*val[k]*x%mod;
    27 }
    28 void down(int k){
    29     if (tag[k]){
    30         upd(L,tag[k]);
    31         upd(R,tag[k]);
    32         tag[k]=0;
    33     }
    34 }
    35 void build(int k,int l,int r,int x){
    36     if (l==r){
    37         val[k]=ksm(x,mod-1-l);
    38         return;
    39     }
    40     build(L,l,mid,x);
    41     build(R,mid+1,r,x);
    42     val[k]=(val[L]+val[R])%mod;
    43 }
    44 void update(int k,int l,int r,int x,int y,int z){
    45     if ((l>y)||(x>r))return;
    46     if ((x<=l)&&(r<=y)){
    47         upd(k,z);
    48         return;
    49     }
    50     down(k);
    51     update(L,l,mid,x,y,z);
    52     update(R,mid+1,r,x,y,z);
    53     sum[k]=(sum[L]+sum[R])%mod;
    54 }
    55 int query(int k,int l,int r,int x,int y){
    56     if ((l>y)||(x>r))return 0;
    57     if ((x<=l)&&(r<=y))return sum[k];
    58     down(k);
    59     return (query(L,l,mid,x,y)+query(R,mid+1,r,x,y))%mod;
    60 }
    61 int main(){
    62     scanf("%d%d%d",&n,&m,&q);
    63     for(int i=1;i<=q;i++)scanf("%d%d",&a[i].l,&a[i].r);
    64     sort(a+1,a+q+1,cmp);
    65     for(int i=1;i<=q;i++){
    66         while ((st[0])&&(a[st[st[0]]].r>=a[i].r))vis[st[st[0]--]]=1;
    67         st[++st[0]]=i;
    68     }
    69     int qq=0;
    70     for(int i=1;i<=q;i++)
    71         if (!vis[i])a[++qq]=a[i];
    72     q=qq;
    73     int inv_m=ksm(m,mod-2);
    74     ans=m;
    75     for(int i=1;i<m;i++){
    76         build(1,1,n,1LL*(m-i)*inv_m%mod);
    77         upd(1,1);
    78         for(int j=1;j<=q;j++){
    79             int s=1LL*i*inv_m%mod;
    80             s=1LL*s*ksm(1LL*(m-i)*inv_m%mod,a[j].r)%mod;
    81             f[j]=1LL*s*query(1,1,n,a[j].l,a[j].r)%mod;
    82             if (a[j].r<n)update(1,1,n,a[j].r+1,n,f[j]);
    83         }
    84         ans=(ans+mod-f[q])%mod;
    85     }
    86     printf("%d",ans);
    87 }
    View Code
  • 相关阅读:
    InfoPath开发误区
    error: 80040111
    EasyUi通过POI 实现导出xls表格功能
    webservice入门
    CXF框架入门(重点)
    Spring整合Shiro
    EasyUi通过OCUpload上传及POI上传 实现导入xls表格功能
    Matlab自定义安装
    一位大学教师对学生的建议:如何做好研究
    What is covariate(协变量)
  • 原文地址:https://www.cnblogs.com/PYWBKTDA/p/14260608.html
Copyright © 2020-2023  润新知