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\n",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\n",ans);
59     }
60 }
61 int main(){
62     init();
63     solve();
64 }
时间: 2024-10-11 00:13:12

BZOJ NOI十连测 第一测 T1的相关文章

BZOJ NOI十连测 第一测 T2

思路:看到这题,就感觉是一道很熟悉的题目: http://www.cnblogs.com/qzqzgfy/p/5535821.html 只不过这题的K最多可以到N,而且边权不再只是1,考试的时候yy了一下做法: 找k次直径,第一次把边取反,要是第二次再取到同样的边,那就把它变成0,毕竟每条边只经过2次嘛,YY的很好,实际上,交上去,5分TAT 后来听以为神犇说不是取0,而是继续取反,每条边取一次就取反一次,woc.. 1 #include<cstdio> 2 #include<cmath

BZOJ NOI十连测 第二测 T2

思路:20%可以搜索.. 1 #include<algorithm> 2 #include<cstdio> 3 #include<cmath> 4 #include<cstring> 5 #include<iostream> 6 #include<time.h> 7 #define ll long long 8 const ll Mod=998244353; 9 ll jc[300005],jcny[300005]; 10 int n

BZOJ NOI 十连测 哈夫曼树

[问题描述]有这样一个经典问题:? 给出一个长度为??的非负整数数组??.? 每次可以选择数组中两个不同位置的数????, ????(?? ?= ??),将它们删除,然后再向数组中加入一个新的元素,值为???? + ????.? 这样一次操作产生的代价是这个新元素的值,即???? + ????.? 例如当前数组中的数为?? = {1, 1, 3, 1},选择??1 = 1, ??4 = 1进行操作后,数组变为{1, 3, 2},代价为2.? 一共会进行?? − 1次操作,要求最小化代价之和.这道

痞子衡嵌入式:测一测i.MXRT1170 Raw NAND启动时间(从POR到进App的Reset_Handler)

大家好,我是痞子衡,是正经搞技术的痞子.今天痞子衡给大家介绍的是恩智浦i.MX RT1170 Raw NAND启动时间. 关于i.MXRT1170这颗划时代的MCU,痞子衡去年10月在其刚发布的时候,专门写过一篇文章介绍过其特点(详见 <终于可以放开聊一聊i.MXRT1170这颗划时代MCU了>),眼看着其上市日期越来越近了,恩智浦软硬件技术支持团队也正在紧锣密鼓地开发SDK以及参考设计.因为官方首次在i.MXRT1170 EVK板上(Rev.B)放了一片旺宏的Raw NAND芯片,而i.MX

《测一测你的颜值指数》武媚娘版

此为<测一测你的颜值指数>武媚娘版,在上一版的基础上作了界面上的修饰.本游戏后台代码完全自主开发,前台是模仿来的. 源码下载地址:http://wx.52tyh.com/thread-207-1-1.html 源码文件结构: 演示地址请用微信扫一扫: 相关主题 <火爆朋友圈:测一测你的颜值指数(带图片上传功能)>

NOI十连测 第五测 T1

1 #include<cstdio> 2 #include<cstring> 3 #include<cmath> 4 #include<iostream> 5 #include<algorithm> 6 int f[257][257],n,type,V[257],g[257][257],ans,cnt; 7 char op[204]; 8 int read(){ 9 int t=0,f=1;char ch=getchar(); 10 while

NOI十连测 第四测 T1

思路:首先每个蚂蚁移速相同,而且碰到就转头,这其实等价于擦肩而过! 看到2n个数互不相同就觉得方便多了:枚举每个数字往左或者往右作为最慢,然后考虑其他蚂蚁有多少种走路方向. (1),走的距离大于m/2 假如红色描述的是一个蚂蚁的移动轨迹,那么蓝色部分左边的蚂蚁只能向左走,蓝色右边的蚂蚁只能向右走. 而蓝色部分中的蚂蚁可以向左也可以向右,方案数为2^n,n为蓝色部分蚂蚁数量. (2),走的距离小于m/2 如图,则蓝色部分左边的蚂蚁只能向左,蓝色部分右边的蚂蚁只能向右.而蓝色部分中间不能有蚂蚁!,这

NOI十连测 DAY3 T1

这么二逼的题考试的时候我想了好久,我真是太弱了... 首先,由于ans都乘上了i*(i-1)/2,实际上要求的就是每个数的所有可能出现次数*这个数的权值. 我们发现,每个数的本质是一样的,我们记一个sum为数的总和,这样只要统计一次就OK了. 我们把每次的选择抽象成有向边,每个状态视为点,这样就构成一个有根树. 如图 我们只考虑1对答案的贡献.如图,在每层计算当前合并对答案的贡献,也就是要能得知我在这个节点选择合并1或者1的联通块,那么我能覆盖到几个叶子节点? 那么就变成O(n)的组合数学题了.

NOI十连测 第六测 T1

思路: 用treap动态维护,记一个sum1,sum2,注意!,写treap如果有删除操作,千万不能把权值相同的分开来..,这在删除的时候会进入死循环,这是一个惨痛的教训... 1 #include<cstdio> 2 #include<cmath> 3 #include<cstring> 4 #include<iostream> 5 #include<algorithm> 6 #include<time.h> 7 #define l