zoukankan      html  css  js  c++  java
  • BZOJ NOI十连测 第一测 T1

     思路:首先考虑t=1的情况,t等于1,那么所有位置的颜色相同,我们不用考虑概率的问题,那么,k+d*x在模d下都相等,我们考虑预处理一个数组s[i][j],代表d为i,起始位置为j的等差数列的和,这个可以证明,当模小于等于sqrt(n)的时候可以完美解决,时间复杂度为N^1.5,对于d大于sqrt(n)的情况,只需要暴力枚举就可以了。

            再考虑t>=2的情况,我们选的颜色一定是颜色数最少的那个,颜色数最少的颜色的期望绝对是最小的,然后,我们分k的左边和k的右边进行计算,我们这里称呼k+d*x的位置,叫做关键位置,假设p[i]为i到k这一段上所有的关键位置全部都是同一个颜色的概率,那么转移,就是p[i+k]=p[i]*(x)/(n-1-x),x为最少的颜色个数。我们可以发现,x<(n-1)/2,p[i]是随指数级衰减的,那么我们只需要枚举一小段,当p[i]<eps时,那么它对答案就几乎没有影响了。

     1 #include<algorithm>
     2 #include<cstdio>
     3 #include<cmath>
     4 #include<cstring>
     5 #include<iostream>
     6 int block,n,m;
     7 int s[2005][2005],a[200005];
     8 const double eps=1e-16;
     9 int read(){
    10     int t=0,f=1;char ch=getchar();
    11     while (ch<'0'||ch>'9'){if (ch=='-') f=-1;ch=getchar();}
    12     while ('0'<=ch&&ch<='9'){t=t*10+ch-'0';ch=getchar();}
    13     return t*f;
    14 }
    15 void init(){
    16     n=read();m=read();
    17     for (int i=1;i<=n;i++) a[i]=read();
    18     block=ceil(sqrt(n))+0.1;
    19     for (int i=1;i<=block;i++)
    20      for (int j=1;j<=i;j++)
    21       for (int k=j;k<=n;k+=i)
    22        s[i][j]+=a[k];
    23 }
    24 void modify(int x,int y){
    25     int T=y-a[x];
    26     for (int i=1;i<=block;i++)
    27       s[i][(x-1)%i+1]+=T;
    28     a[x]=y;  
    29 }
    30 double deal(int k,int d){
    31     if (d<=block) return s[d][(k-1)%d+1];
    32     double res=0;
    33     for (int i=(k-1)%d+1;i<=n;i+=d)
    34      res+=(double)a[i];
    35     return res; 
    36 }
    37 void solve(){
    38     while (m--){
    39         int opt=read();
    40         if (opt==1){
    41             int x=read(),y=read();
    42             modify(x,y);continue;
    43         }
    44         int num=0x7fffffff,t,k,d;
    45         t=read();k=read();d=read();for (int i=1;i<=t;i++){int l=read();num=std::min(num,l);}
    46         if (t==1) {printf("%.4f
    ",deal(k,d));continue;}
    47         double ans=(double)a[k],p=1;
    48         int N=num;
    49         for (int i=k+d,Num=n-1;i<=n&&num>0;i+=d,Num--,num--){
    50             p=p*num/Num;ans+=p*a[i];
    51             if (p<eps&&n>=1000) break;
    52         }
    53         num=N;p=1;
    54         for (int i=k-d,Num=n-1;i>=1&&num>0;i-=d,Num--,num--){
    55             p=p*num/Num;ans+=p*a[i];
    56             if (p<eps&&n>=1000) break;
    57         }
    58         printf("%.4f
    ",ans);
    59     }
    60 }
    61 int main(){
    62     init();
    63     solve();
    64 }
  • 相关阅读:
    CentOS-6.9搭建NFS服务器
    CentOS6.9-搭建vsftpd三种模式及参数详解
    CentOS-7.3 MySQL数据库入门简介及源码编译安装MySQL服务
    CentOS7.3系统vsftpd服务简介及vsftpd的三种模式的搭建
    安装CentOS7.4 Linux操作系统
    windows server2008R2 64位 配置 mysql-8.0.15-winx64
    怎么删除服务中的mysql服务
    mysql-8.0.15-winx64 解压版安装 图文详解
    命令行下创建MySQL数据库与创建用户以及授权
    windows 2008r2+php5.6.28环境搭建详细过程
  • 原文地址:https://www.cnblogs.com/qzqzgfy/p/5588689.html
Copyright © 2011-2022 走看看