题目链接  Eyes Closed

题意  两个人玩一个游戏,现在有两种操作:

1、两个人格子挑选一个区间,保证两个的区间不相交。在这两个区间里面各选出一个数,交换这两个数。

2、挑选一个区间,求这个区间的和的期望。

对于第一种操作,先求出两个区间的长度$len1$和$len2$,再求出两个区间的期望和$s1$和$s2$。

对于第一个区间,我们先把这个区间里的所有数(期望值)乘上$(len1 - 1)/(len1)$,再加上$s2/len1/len2$

对于第二个区间,我们先把这个区间里的所有数(期望值)乘上$(len2 - 1)/(len2)$,再加上$s1/len1/len2$

线段树维护这两个操作即可。

  1. #include <bits/stdc++.h>
  2.  
  3. using namespace std;
  4.  
  5. #define rep(i, a, b) for (int i(a); i <= (b); ++i)
  6. #define dec(i, a, b) for (int i(a); i >= (b); --i)
  7. #define ls (i << 1)
  8. #define rs (i << 1 | 1)
  9. #define mid ((L + R) >> 1)
  10. #define lson i << 1, L, mid
  11. #define rson i << 1 | 1, mid + 1, R
  12.  
  13. typedef long long LL;
  14.  
  15. const int N = 4e5 + 10;
  16.  
  17. double add[N], mul[N], s[N];
  18. int n, q;
  19.  
  20. void pushup(int i){ s[i] = s[ls] + s[rs]; }
  21.  
  22. void pushdown(int i, int L, int R){
  23. s[ls] = mul[i] * s[ls] + add[i] * (mid - L + 1);
  24. mul[ls] *= mul[i];
  25. add[ls] = mul[i] * add[ls] + add[i];
  26. s[rs] = mul[i] * s[rs] + add[i] * (R - mid);
  27. mul[rs] *= mul[i];
  28. add[rs] = mul[i] * add[rs] + add[i];
  29. add[i] = 0;
  30. mul[i] = 1.0;
  31. }
  32.  
  33. void build(int i, int L, int R){
  34. add[i] = 0, mul[i] = 1;
  35. s[i] = 0;
  36. if (L == R){ scanf("%lf", s + i); return; }
  37. build(lson);
  38. build(rson);
  39. pushup(i);
  40. }
  41.  
  42. void add_update(int i, int L, int R, int l, int r, double val){
  43. if (l <= L && R <= r){
  44. s[i] += (R - L + 1) * val;
  45. add[i] += val;
  46. return;
  47. }
  48.  
  49. pushdown(i, L, R);
  50. if (l <= mid) add_update(lson, l, r, val);
  51. if (r > mid) add_update(rson, l, r, val);
  52. pushup(i);
  53. }
  54.  
  55. void mul_update(int i, int L, int R, int l, int r, double val){
  56. if (l <= L && R <= r){
  57. s[i] *= val;
  58. mul[i] *= val;
  59. add[i] *= val;
  60. return;
  61. }
  62.  
  63. pushdown(i, L, R);
  64. if (l <= mid) mul_update(lson, l, r, val);
  65. if (r > mid) mul_update(rson, l, r, val);
  66. pushup(i);
  67. }
  68.  
  69. double query(int i, int L, int R, int l, int r){
  70. if (l <= L && R <= r) return s[i];
  71. double ret = 0;
  72. pushdown(i, L, R);
  73. if (l <= mid) ret += query(lson, l, r);
  74. if (r > mid) ret += query(rson, l, r);
  75. pushup(i);
  76. return ret;
  77. }
  78.  
  79. int main(){
  80.  
  81. scanf("%d%d", &n, &q);
  82. build(1, 1, n);
  83.  
  84. while (q--){
  85. int op;
  86. scanf("%d", &op);
  87. if (op == 1){
  88. int l1, r1, l2, r2;
  89. scanf("%d%d%d%d", &l1, &r1, &l2, &r2);
  90. double s1 = query(1, 1, n, l1, r1);
  91. double s2 = query(1, 1, n, l2, r2);
  92. double len1 = r1 - l1 + 1;
  93. double len2 = r2 - l2 + 1;
  94. mul_update(1, 1, n, l1, r1, 1.0 * (len1 - 1) / len1);
  95. mul_update(1, 1, n, l2, r2, 1.0 * (len2 - 1) / len2);
  96. add_update(1, 1, n, l1, r1, 1.0 / len1 / len2 * s2);
  97. add_update(1, 1, n, l2, r2, 1.0 / len1 / len2 * s1);
  98. }
  99.  
  100. else{
  101. int l, r;
  102. scanf("%d%d", &l, &r);
  103. printf("%.12f\n", query(1, 1, n, l, r));
  104. }
  105. }
  106.  
  107. return 0;
  108. }

Codeforces 895E Eyes Closed(线段树)的更多相关文章

  1. Buses and People CodeForces 160E 三维偏序+线段树

    Buses and People CodeForces 160E 三维偏序+线段树 题意 给定 N 个三元组 (a,b,c),现有 M 个询问,每个询问给定一个三元组 (a',b',c'),求满足 a ...

  2. CodeForces 877E DFS序+线段树

    CodeForces 877E DFS序+线段树 题意 就是树上有n个点,然后每个点都有一盏灯,给出初始的状态,1表示亮,0表示不亮,然后有两种操作,第一种是get x,表示你需要输出x的子树和x本身 ...

  3. [Codeforces 1197E]Culture Code(线段树优化建图+DAG上最短路)

    [Codeforces 1197E]Culture Code(线段树优化建图+DAG上最短路) 题面 有n个空心物品,每个物品有外部体积\(out_i\)和内部体积\(in_i\),如果\(in_i& ...

  4. [Codeforces 1199D]Welfare State(线段树)

    [Codeforces 1199D]Welfare State(线段树) 题面 给出一个长度为n的序列,有q次操作,操作有2种 1.单点修改,把\(a_x\)修改成y 2.区间修改,把序列中值< ...

  5. [Codeforces 316E3]Summer Homework(线段树+斐波那契数列)

    [Codeforces 316E3]Summer Homework(线段树+斐波那契数列) 顺便安利一下这个博客,给了我很大启发(https://gaisaiyuno.github.io/) 题面 有 ...

  6. Codeforces Gym 100231B Intervals 线段树+二分+贪心

    Intervals 题目连接: http://codeforces.com/gym/100231/attachments Description 给你n个区间,告诉你每个区间内都有ci个数 然后你需要 ...

  7. Codeforces 482B Interesting Array(线段树)

    题目链接:Codeforces 482B Interesting Array 题目大意:给定一个长度为N的数组,如今有M个限制,每一个限制有l,r,q,表示从a[l]~a[r]取且后的数一定为q,问是 ...

  8. codeforces 383C Propagating tree 线段树

    http://codeforces.com/problemset/problem/383/C 题目就是说,  给一棵树,将一个节点的值+val, 那么它的子节点都会-val, 子节点的子节点+val. ...

  9. CodeForces 228D. Zigzag(线段树暴力)

    D. Zigzag time limit per test 3 seconds memory limit per test 256 megabytes input standard input out ...

随机推荐

  1. DeepFaceLab小白入门(1):软件简介!

    简介 DeepFaceLab是一种利用深度学习识别和交换图片和视频中的人脸的工具 这是一个github上的开源项目,所有人都可以查看源代码也能免费使用.个人认为这个项目的最大优点就是安装超级简单,几乎 ...

  2. Python基础学习总结__Day3

    一.集合 1.特性:无序且天生去重,格式为{} 2.作用: (1)去重 (2)关系测试 3.可调用函数(常见对列表操作) (1)取交集:A.intersection(B) (2)取并集:A.union ...

  3. python基础-面向对象的三大特征

    继承 单继承 父类 基类 子类 派生类 继承:是面向对象软件技术当中的一个概念,如果一个类别A“继承自”另一个类别B,就把这个A称为“B的子类别”,而把B称为“A的父类别”也可以称“B是A的超类”. ...

  4. ax=1(%b) 求最小逆元

    定理一:如果d = gcd(a, b),则必能找到正的或负的整数x和y,使 d = a*x+ b*y. 定理二:若gcd(a, b) = ,则方程ax ≡ c (mod b)在[, b-]上有唯一解. ...

  5. Linux学习-用 make 进行宏编译

    为什么要用 make 先来想象一个案例,假设我的执行档里面包含了四个原始码文件,分别是 main.c haha.c sin_value.c cos_value.c 这四个文件,这四个文件的目的是: m ...

  6. dubbo rpc filter实现剖析(二)

    2.6.3版本,之前读的是2.4.9版本 本篇主要阐述dubbo rpc的filter的实现,包括作用,用法,原理,与Spring Cloud在这些能力的对比. 整个filter列表的获取过程在 co ...

  7. Linux中 find 常见用法示例

    Linux中find常见用法示例 #find path -option [ -print ] [ -exec -ok command ] {} \; #-print 将查找到的文件输出到标准输出 #- ...

  8. 一张图展示:用两个栈来实现一个队列,完成队列的Push和Pop操作

    一  基本思路 将s1作为存储空间,以s2作为临时缓冲区. 入队时,将元素压入s1. 出队时,将s1的元素逐个“倒入”(弹出并压入)s2,将s2的顶元素弹出作为出队元素,之后再将s2剩下的元素逐个“倒 ...

  9. ubuntu14.04 不能关机,一直停在关机界面

    1.emotion: 最近在使用Ubuntu14.04 LTS时,输入shutdown -h now之后,Ubuntu就一直停在关机界面,始终不能shutdown,不得不手动按下电源button.忍受 ...

  10. layer弹窗在键盘按回车将反复刷新

      条件:弹窗后不做任何点击操作或者聚焦操作对于layer.load,弹出后反复按回车,load层将不断刷新,即使设置了自动消失也只有等不按回车键才会生效.对于layer iframe层有表单就更糟糕 ...