【BZOJ4821】[SDOI2017]相关分析(线段树)

题面

BZOJ

洛谷

题解

看看询问要求的东西是什么。把所有的括号拆开,不难发现要求的就是\(\sum x,\sum y,\sum xy,\sum x^2\)

考虑修改操作。先是区间加法,对于\(\sum x,\sum y\)而言直接加就好了。

而\(\sum (x+S)^2=\sum (x^2+S^2+2Sx)\),分开维护一下也做完了。

\(\sum (x+S)(y+T)\)也只需要把括号拆开之后分开维护就行了。

另外一种是区间赋值,我们看做先令\(x_i=y_i=i\),然后再对应的加上\(S,T\)就好了。注意一下这里要把之前操作里面的\(S,T\)标记清空。

  1. #include<iostream>
  2. #include<cstdio>
  3. #include<cstdlib>
  4. #include<cstring>
  5. #include<cmath>
  6. #include<algorithm>
  7. #include<vector>
  8. using namespace std;
  9. #define MAX 100100
  10. #define lson (now<<1)
  11. #define rson (now<<1|1)
  12. #define ll long long
  13. inline int read()
  14. {
  15. int x=0;bool t=false;char ch=getchar();
  16. while((ch<'0'||ch>'9')&&ch!='-')ch=getchar();
  17. if(ch=='-')t=true,ch=getchar();
  18. while(ch<='9'&&ch>='0')x=x*10+ch-48,ch=getchar();
  19. return t?-x:x;
  20. }
  21. int n,m,X[MAX],Y[MAX];
  22. struct Node{double x,y,xy,xx,S,T;int eql;}t[MAX<<2];
  23. Node operator+(Node a,Node b){return (Node){a.x+b.x,a.y+b.y,a.xy+b.xy,a.xx+b.xx,0,0,0};}
  24. void pushup(int now)
  25. {
  26. t[now].x=t[lson].x+t[rson].x;
  27. t[now].y=t[lson].y+t[rson].y;
  28. t[now].xx=t[lson].xx+t[rson].xx;
  29. t[now].xy=t[lson].xy+t[rson].xy;
  30. }
  31. void Build(int now,int l,int r)
  32. {
  33. if(l==r)
  34. {
  35. t[now].x=X[l],t[now].y=Y[l];
  36. t[now].xx=t[now].x*t[now].x;
  37. t[now].xy=t[now].x*t[now].y;
  38. return;
  39. }
  40. int mid=(l+r)>>1;
  41. Build(lson,l,mid);Build(rson,mid+1,r);
  42. pushup(now);
  43. }
  44. double S1(int x){return 0.5*x*(x+1);}
  45. double S2(int x){return 1.0/6*x*(x+1)*(x+x+1);}
  46. void addST(int now,int l,int r,double S,double T)
  47. {
  48. int len=r-l+1;
  49. t[now].xx+=len*S*S+2*S*t[now].x;
  50. t[now].xy+=t[now].x*T+t[now].y*S+len*S*T;
  51. t[now].x+=len*S;t[now].y+=len*T;
  52. t[now].S+=S;t[now].T+=T;
  53. }
  54. void addeql(int now,int l,int r)
  55. {
  56. t[now].x=t[now].y=S1(r)-S1(l-1);
  57. t[now].xx=t[now].xy=S2(r)-S2(l-1);
  58. t[now].eql=1;t[now].S=t[now].T=0;
  59. }
  60. void pushdown(int now,int l,int r)
  61. {
  62. int mid=(l+r)>>1;
  63. if(t[now].eql)
  64. {
  65. addeql(lson,l,mid);addeql(rson,mid+1,r);
  66. t[now].eql=0;
  67. }
  68. if(t[now].S||t[now].T)
  69. {
  70. addST(lson,l,mid,t[now].S,t[now].T);
  71. addST(rson,mid+1,r,t[now].S,t[now].T);
  72. t[now].S=t[now].T=0;
  73. }
  74. }
  75. void Modify(int now,int l,int r,int L,int R,double S,double T)
  76. {
  77. if(L<=l&&r<=R){addST(now,l,r,S,T);return;}
  78. int mid=(l+r)>>1;pushdown(now,l,r);
  79. if(L<=mid)Modify(lson,l,mid,L,R,S,T);
  80. if(R>mid)Modify(rson,mid+1,r,L,R,S,T);
  81. pushup(now);
  82. }
  83. void Modify(int now,int l,int r,int L,int R)
  84. {
  85. if(L<=l&&r<=R){addeql(now,l,r);return;}#include<iostream>
  86. #include<cstdio>
  87. #include<cstdlib>
  88. #include<cstring>
  89. #include<cmath>
  90. #include<algorithm>
  91. #include<vector>
  92. using namespace std;
  93. #define MAX 100100
  94. #define lson (now<<1)
  95. #define rson (now<<1|1)
  96. #define ll long long
  97. inline int read()
  98. {
  99. int x=0;bool t=false;char ch=getchar();
  100. while((ch<'0'||ch>'9')&&ch!='-')ch=getchar();
  101. if(ch=='-')t=true,ch=getchar();
  102. while(ch<='9'&&ch>='0')x=x*10+ch-48,ch=getchar();
  103. return t?-x:x;
  104. }
  105. int n,m,X[MAX],Y[MAX];
  106. struct Node{double x,y,xy,xx,S,T;int eql;}t[MAX<<2];
  107. Node operator+(Node a,Node b){return (Node){a.x+b.x,a.y+b.y,a.xy+b.xy,a.xx+b.xx,0,0,0};}
  108. void pushup(int now)
  109. {
  110. t[now].x=t[lson].x+t[rson].x;
  111. t[now].y=t[lson].y+t[rson].y;
  112. t[now].xx=t[lson].xx+t[rson].xx;
  113. t[now].xy=t[lson].xy+t[rson].xy;
  114. }
  115. void Build(int now,int l,int r)
  116. {
  117. if(l==r)
  118. {
  119. t[now].x=X[l],t[now].y=Y[l];
  120. t[now].xx=t[now].x*t[now].x;
  121. t[now].xy=t[now].x*t[now].y;
  122. return;
  123. }
  124. int mid=(l+r)>>1;
  125. Build(lson,l,mid);Build(rson,mid+1,r);
  126. pushup(now);
  127. }
  128. double S1(int x){return 0.5*x*(x+1);}
  129. double S2(int x){return 1.0/6*x*(x+1)*(x+x+1);}
  130. void addST(int now,int l,int r,double S,double T)
  131. {
  132. int len=r-l+1;
  133. t[now].xx+=len*S*S+2*S*t[now].x;
  134. t[now].xy+=t[now].x*T+t[now].y*S+len*S*T;
  135. t[now].x+=len*S;t[now].y+=len*T;
  136. t[now].S+=S;t[now].T+=T;
  137. }
  138. void addeql(int now,int l,int r)
  139. {
  140. t[now].x=t[now].y=S1(r)-S1(l-1);
  141. t[now].xx=t[now].xy=S2(r)-S2(l-1);
  142. t[now].eql=1;t[now].S=t[now].T=0;
  143. }
  144. void pushdown(int now,int l,int r)
  145. {
  146. int mid=(l+r)>>1;
  147. if(t[now].eql)
  148. {
  149. addeql(lson,l,mid);addeql(rson,mid+1,r);
  150. t[now].eql=0;
  151. }
  152. if(t[now].S||t[now].T)
  153. {
  154. addST(lson,l,mid,t[now].S,t[now].T);
  155. addST(rson,mid+1,r,t[now].S,t[now].T);
  156. t[now].S=t[now].T=0;
  157. }
  158. }
  159. void Modify(int now,int l,int r,int L,int R,double S,double T)
  160. {
  161. if(L<=l&&r<=R){addST(now,l,r,S,T);return;}
  162. int mid=(l+r)>>1;pushdown(now,l,r);
  163. if(L<=mid)Modify(lson,l,mid,L,R,S,T);
  164. if(R>mid)Modify(rson,mid+1,r,L,R,S,T);
  165. pushup(now);
  166. }
  167. void Modify(int now,int l,int r,int L,int R)
  168. {
  169. if(L<=l&&r<=R){addeql(now,l,r);return;}
  170. int mid=(l+r)>>1;pushdown(now,l,r);
  171. if(L<=mid)Modify(lson,l,mid,L,R);
  172. if(R>mid)Modify(rson,mid+1,r,L,R);
  173. pushup(now);
  174. }
  175. Node Query(int now,int l,int r,int L,int R)
  176. {
  177. if(l==L&&r==R)return t[now];
  178. int mid=(l+r)>>1;pushdown(now,l,r);
  179. if(R<=mid)return Query(lson,l,mid,L,R);
  180. if(L>mid)return Query(rson,mid+1,r,L,R);
  181. return Query(lson,l,mid,L,mid)+Query(rson,mid+1,r,mid+1,R);
  182. }
  183. int main()
  184. {
  185. n=read();m=read();
  186. for(int i=1;i<=n;++i)X[i]=read();
  187. for(int i=1;i<=n;++i)Y[i]=read();
  188. Build(1,1,n);
  189. while(m--)
  190. {
  191. int opt=read(),l=read(),r=read();
  192. if(opt==1)
  193. {
  194. Node a=Query(1,1,n,l,r);
  195. double u=a.xy-a.x*a.y/(r-l+1);
  196. double v=a.xx-a.x*a.x/(r-l+1);
  197. printf("%.10lf\n",u/v);
  198. }
  199. else
  200. {
  201. double S=read(),T=read();
  202. if(opt==3)Modify(1,1,n,l,r);
  203. Modify(1,1,n,l,r,S,T);
  204. }
  205. }
  206. return 0;
  207. }
  208. int mid=(l+r)>>1;pushdown(now,l,r);
  209. if(L<=mid)Modify(lson,l,mid,L,R);
  210. if(R>mid)Modify(rson,mid+1,r,L,R);
  211. pushup(now);
  212. }
  213. Node Query(int now,int l,int r,int L,int R)
  214. {
  215. if(l==L&&r==R)return t[now];
  216. int mid=(l+r)>>1;pushdown(now,l,r);
  217. if(R<=mid)return Query(lson,l,mid,L,R);
  218. if(L>mid)return Query(rson,mid+1,r,L,R);
  219. return Query(lson,l,mid,L,mid)+Query(rson,mid+1,r,mid+1,R);
  220. }
  221. int main()
  222. {
  223. n=read();m=read();
  224. for(int i=1;i<=n;++i)X[i]=read();
  225. for(int i=1;i<=n;++i)Y[i]=read();
  226. Build(1,1,n);
  227. while(m--)
  228. {
  229. int opt=read(),l=read(),r=read();
  230. if(opt==1)
  231. {
  232. Node a=Query(1,1,n,l,r);
  233. double u=a.xy-a.x*a.y/(r-l+1);
  234. double v=a.xx-a.x*a.x/(r-l+1);
  235. printf("%.10lf\n",u/v);
  236. }
  237. else
  238. {
  239. double S=read(),T=read();
  240. if(opt==3)Modify(1,1,n,l,r);
  241. Modify(1,1,n,l,r,S,T);
  242. }
  243. }
  244. return 0;
  245. }

【BZOJ4821】[SDOI2017]相关分析(线段树)的更多相关文章

  1. 【BZOJ4821】[Sdoi2017]相关分析 线段树

    [BZOJ4821][Sdoi2017]相关分析 Description Frank对天文学非常感兴趣,他经常用望远镜看星星,同时记录下它们的信息,比如亮度.颜色等等,进而估算出星星的距离,半径等等. ...

  2. [Sdoi2017]相关分析 [线段树]

    [Sdoi2017]相关分析 题意:沙茶线段树 md其实我考场上还剩一个多小时写了40分 其实当时写正解也可以吧1h也就写完了不过还要拍一下 正解代码比40分短2333 #include <io ...

  3. BZOJ 4821 [Sdoi2017]相关分析 ——线段树

    打开题面,看到许多$\sum$ woc,好神啊,SDOI好强啊 然后展开之后,woc,SDOI好弱啊,怎么T3出个线段树裸题啊. 最后写代码的时候,woc,SDOI怎么出个这么码农的题啊,怎么调啊. ...

  4. 洛谷P3707 [SDOI2017]相关分析(线段树)

    题目描述 Frank对天文学非常感兴趣,他经常用望远镜看星星,同时记录下它们的信息,比如亮度.颜色等等,进而估算出星星的距离,半径等等. Frank不仅喜欢观测,还喜欢分析观测到的数据.他经常分析两个 ...

  5. BZOJ 4821: [Sdoi2017]相关分析 线段树 + 卡精

    考试的时候切掉了,然而卡精 + 有一个地方忘开 $long long$,完美挂掉 $50$pts. 把式子化简一下,然后直接拿线段树来维护即可. Code: // luogu-judger-enabl ...

  6. BZOJ.4821.[SDOI2017]相关分析(线段树)

    BZOJ LOJ 洛谷 恶心的拆式子..然后就是要维护\(\sum x_i,\ \sum y_i,\ \sum x_iy_i,\ \sum x_i^2\). 操作三可以看成初始化一遍,然后同操作二. ...

  7. SDOI2017相关分析 线段树

    题目 https://loj.ac/problem/2005 思路 \[ \sum_{L}^{R}{(x_i-x)^{2}} \] \[ \sum_{L}^{R}{(x_i^2-2*x_i*x+x^{ ...

  8. 【BZOJ4821】【SDOI2017】相关分析 [线段树]

    相关分析 Time Limit: 10 Sec  Memory Limit: 128 MB[Submit][Status][Discuss] Description Frank对天文学非常感兴趣,他经 ...

  9. luogu3707 相关分析 (线段树)

    把式子展开以后会发现,可以用线段树维护$x,y,x*y,x^2$分别的区间和 然后操作有区间加和区间修改 这个pushdown的时候,如果改和加的标记同时存在,那一定是先改再加,要不然加的标记已经被清 ...

  10. BZOJ4821 SDOI2017相关分析(线段树)

    纯粹的码农题.维护x的和.y的和.xy的和.x2的和即可.可能会炸long long. #include<iostream> #include<cstdio> #include ...

随机推荐

  1. 绍一集训Round#1

    到了之后看题,T1一看发现真熟悉,和之前做的一道题真的像,然后内心: 这里是绍一啊,不可能就出这么简单的题 我题意没理解错啊,这不是单独计算每条边的贡献么 维护一个人数的大小,然后直接搞一波就可以了吧 ...

  2. Unity 敌人波次设计

    一.平均时间随机敌人 将所有种类敌人预制物体放在一个列表里面,每隔时间T从列表中随机选出一个生成在场景中. 二.时间加权紧迫度随机敌人 在随机情况下每种敌人出现的概率近似相等,当敌人种类较多时,有可能 ...

  3. if...else 小练习

    # 需求:猜年龄,可以让用户最多猜三次 age = 60 for i in range(3): guess = int(input("Input Age: ")) if guess ...

  4. python基础学习笔记(四)

    列表 本节继续讨论列表不同元组和字符串的地方:列表是可变的(mutable)----可以改变列表的内容,并且列表有很多有用的.专门的方法. List函数可以将一个字符串拆分成列表. >>& ...

  5. linux及安全第六周总结

    进程控制块pcb——task_struct 操作系统三大功能: 进程管理(核心) 内存管理 文件系统 为了管理进程,内核必须对每个进程进行清晰的描述,进程描述符提供了内核所需了解的进程信息: 进程状态 ...

  6. MSF MS11-050/10-087/Adobe攻击实践及内存保护技术

    MSF MS11-050/10-087/Adobe攻击实践及内存保护技术 内存攻击指的是攻击者利用软件安全漏洞,构造恶意输入导致软件在处理输入数据时出现非预期错误,将输入数据写入内存中的某些特定敏感位 ...

  7. Proxy 示例

    package cn.proxy03; import java.lang.reflect.InvocationHandler; import java.lang.reflect.Method; imp ...

  8. 第三个spring冲刺第8天

    今天,我们忙于完成精美的背景,还有难度的具体设置,如何达到最理想化,为此我们今天主要是做了开会讨论,但还没有完全确定好结论,明天就应该能做出结论,然后修改后台的难度设置了.

  9. python中的hasattr()、getattr()、setattr()

    hasattr()的用法和理解--hasattr(obj, target) 判断对象obj中是否含有,目标target属性,然后返回布尔值,如果有返回True,没有返回False. >>& ...

  10. Tomcat启动失败

    前景:使用的是tomcat9.0,配置好后,使用一切正常,刷慕课跟着做练习,也一切正常.出事在于,老师为了方便直接拷之前写的一个项目,我照做了,老师改了虚拟路径了,我忘记改了,然后跑了一下项目就出毛病 ...