• 奥义商店


    有一个商店,n个物品,每个物品有一个价格和一种颜色。

    有m个操作,操作有两种,一种是修改一个位置的价格,另一种是购买,每次购买指定一个公差d和一个位置k,找到包含这个位置k公差为d的同色最长等差数列,买下所有物品。让你给这个位置染成t种颜色中的一种(你来指定),其他位置会随机染成t种颜色之一,并保证这n-1个物品中第j种颜色的恰好有c[j]个。求最小期望花费保留四位小数。

    注意询问相互独立,询问不会买走物品。

    1<=n,m<=10^5,∑t<=2*10^5。

    样例输入:

    3 3
    1 1 1
    2 2 1 1 1 1
    1 2 2
    2 2 3 1 1 1
    样例输出
    1.5000
    2.0000

    先考虑t=1时

    这样我们就要找到所有mod d与k同余的数之和

    考虑分块考虑

    lim=√n

    当d<=lim时,它的元素个数会>lim,预处理出和每一个d<=lim的和

    当d>lim时,直接枚举求和

    接下来考虑t>1,那么看完分析就知道为什么t=1要单独考虑

    要使花的钱最少,你选择的肯定是出现概率最少的颜色,设它有$c$个

    假设直到$k+x*d$有贡献,那么要求$k+d,k+2*d,....k+x*d$都是这个颜色

    设$p[i]$表示到$k+i*d$有贡献

    这样染色的方案数,那么剩下$n-1-p$个只能有$c-p$个为这个颜色,方案数就是$C_{n-1-p}^{c-p}$

    而概率就是$frac{C_{n-1-p}^{c-p}}{C_{n-1}^{c}}$。

    可得$p[i]=p[i-1]*frac{c-i+1}{n-i}$

    但是这样也会超时

    我们发现$t>1$时$c<=(n-1)/2$

    于是$frac{frac{n-1}{2}-i+1}{n-i}<=0.5$

    所以p会指数级下降,所以到了大概100位就基本为0了

    所以复杂度$O(m√n+m*100)$

     1 #include<iostream>
     2 #include<cstdio>
     3 #include<cmath>
     4 #include<cstring>
     5 #include<algorithm>
     6 #include<cmath>
     7 using namespace std;
     8 double ans;
     9 int s[401][100001],v[100001];
    10 double p[101];
    11 int n,q,lim,opt,minc,c[200001];
    12 int main()
    13 {int i,j,t,x,k,d;
    14   double y;
    15   freopen("lzz.in","r",stdin);
    16   freopen("lzz.out","w",stdout);
    17   cin>>n>>q;
    18   lim=sqrt(n);
    19   for (i=1;i<=n;i++)
    20     {
    21       scanf("%d",&v[i]);
    22     }
    23   for (i=1;i<=lim;i++)
    24     {
    25       for (j=1;j<=n;j++)
    26       {
    27         s[i][j%i]+=v[j];
    28       }
    29     }
    30   while (q--)
    31     {
    32       scanf("%d",&opt);
    33       if (opt==1)
    34       {
    35         scanf("%d%lf",&x,&y);
    36         for (i=1;i<=lim;i++)
    37           {
    38             s[i][x%i]+=y-v[x];
    39           }
    40         v[x]=y;
    41       }
    42       else
    43       {
    44         scanf("%d%d%d",&t,&k,&d);
    45         minc=2e9;
    46         for (i=1;i<=t;i++)
    47           {
    48             scanf("%d",&c[i]);
    49             minc=min(minc,c[i]);
    50           }
    51         if (t==1)
    52           {
    53             ans=0;
    54             if (d<=lim)
    55             {
    56               ans=s[d][k%d];
    57             }
    58             else
    59             {
    60               for (i=k;i<=n;i+=d) ans+=v[i];
    61               for (i=k-d;i>=1;i-=d) ans+=v[i];
    62             }
    63             printf("%.4lf
    ",ans);
    64           }
    65         else
    66           {
    67             p[0]=1;
    68             ans=0;
    69             for (i=1;i<=100;i++)
    70             if (i>minc) p[i]=0;
    71             else p[i]=p[i-1]*(double)(minc-i+1)/(double)(n-i);
    72             for (i=k,t=0;i<=n&&t<=100;i+=d,t++)
    73             ans+=v[i]*p[t];
    74             for (i=k-d,t=1;i>=1&&t<=100;i-=d,t++)
    75             ans+=v[i]*p[t];
    76             printf("%.4lf
    ",ans);
    77           }
    78       }
    79     }
    80 }
  • 相关阅读:
    ESB企业服务总线
    OpenStack的架构详解[精51cto]
    用MSBuild和Jenkins搭建持续集成环境(1)[收集]
    Hmac算法
    自定义JDBCUtils工具类
    读取JDBC配置文件的二种方式
    哈希算法
    BouncyCastle
    签名算法
    3种查看java字节码的方式
  • 原文地址:https://www.cnblogs.com/Y-E-T-I/p/8672232.html
Copyright © 2020-2023  润新知