题面:BZOJ传送门 洛谷传送门

线段树好题

题目保证$a$一定是正整数,容易发现计算结果是单调的

我们把询问离线,并按照从小到大排序

某次操作可能导致某些位置达到边界$L/R$

根据单调性的结论

这些位置一定是从$1$向右扩展或者$Q$向左扩展

可以二分找到这个区间,然后区间覆盖

那么修改操作,归根结底是这$4$种操作:

1.区间加减 2.区间乘法 3.区间覆盖 4.区间每个位置加某个数*对应位置的固定权值

比较复杂,考虑抽象化这个问题,把它写成一个函数

$f(a,b,c)=a*f(a,b,c)+b*X_{i}+c$

上述四种操作变成

$1.f(1,0,x) 2.(x,0,0) 3.(0,0,x) 4.(1,x,0)$

我们只需要每次把值往里面带,然后用线段树维护这个函数就行了

注意下推标记的顺序

  1. #include <cstdio>
  2. #include <cstring>
  3. #include <algorithm>
  4. #define N1 100010
  5. #define ll long long
  6. using namespace std;
  7.  
  8. int gint()
  9. {
  10. int ret=,fh=; char c=getchar();
  11. while(c<''||c>''){if(c=='-')fh=-;c=getchar();}
  12. while(c>=''&&c<=''){ret=ret*+c-'';c=getchar();}
  13. return ret*fh;
  14. }
  15.  
  16. int n;
  17. ll ml,mr;
  18. struct node{int id,x;ll ans;}q[N1];
  19. int cmp1(node s1,node s2){return s1.x<s2.x;}
  20. int cmp2(node s1,node s2){return s1.id<s2.id;}
  21. int v[N1],p[N1],f[N1],m;
  22.  
  23. struct SEG{
  24. #define M1 (N1<<2)
  25. ll mi[M1],ma[M1],a[M1],b[M1],c[M1];
  26. void pushup(int rt)
  27. {
  28. mi[rt]=mi[rt<<];
  29. ma[rt]=ma[rt<<|];
  30. }
  31. void pushdown(int l,int r,int rt)
  32. {
  33. int mid=(l+r)>>;
  34. if(a[rt]==&&!b[rt]&&!c[rt]) return;
  35. a[rt<<]=a[rt]*a[rt<<];
  36. a[rt<<|]=a[rt]*a[rt<<|];
  37. b[rt<<]=a[rt]*b[rt<<]+b[rt];
  38. b[rt<<|]=a[rt]*b[rt<<|]+b[rt];
  39. c[rt<<]=a[rt]*c[rt<<]+c[rt];
  40. c[rt<<|]=a[rt]*c[rt<<|]+c[rt];
  41. mi[rt<<]=a[rt]*mi[rt<<]+b[rt]*v[l]+c[rt];
  42. mi[rt<<|]=a[rt]*mi[rt<<|]+b[rt]*v[mid+]+c[rt];
  43. ma[rt<<]=a[rt]*ma[rt<<]+b[rt]*v[mid]+c[rt];
  44. ma[rt<<|]=a[rt]*ma[rt<<|]+b[rt]*v[r]+c[rt];
  45. a[rt]=; b[rt]=c[rt]=;
  46. }
  47. void update(int L,int R,int l,int r,int rt,ll A,ll B,ll C)
  48. {
  49. if(L<=l&&r<=R)
  50. {
  51. a[rt]=A*a[rt];
  52. b[rt]=A*b[rt]+B;
  53. c[rt]=A*c[rt]+C;
  54. mi[rt]=A*mi[rt]+B*v[l]+C;
  55. ma[rt]=A*ma[rt]+B*v[r]+C;
  56. return;
  57. }
  58. int mid=(l+r)>>;
  59. if(L<=mid) update(L,R,l,mid,rt<<,A,B,C);
  60. if(R>mid) update(L,R,mid+,r,rt<<|,A,B,C);
  61. pushup(rt);
  62.  
  63. }
  64. ll calc1(int x,ll rt,ll A,ll B,ll C){return A*mi[rt]+B*v[x]+C;}
  65. ll calc2(int x,ll rt,ll A,ll B,ll C){return A*ma[rt]+B*v[x]+C;}
  66. ll de;
  67. int qleft(int l,int r,int rt,int A,int B,int C)
  68. {
  69. if(l==r){ if(calc2(r,rt,A,B,C)>ml) return l-; return l; }
  70. int mid=(l+r)>>; pushdown(l,r,rt); de=calc2(mid,rt<<,A,B,C);
  71. if(calc2(mid,rt<<,A,B,C)<=ml) return qleft(mid+,r,rt<<|,A,B,C);
  72. else return qleft(l,mid,rt<<,A,B,C);
  73. }
  74. int qright(int l,int r,int rt,int A,int B,int C)
  75. {
  76. if(l==r){ if(calc1(l,rt,A,B,C)<mr) return l+; return l; }
  77. int mid=(l+r)>>; pushdown(l,r,rt); de=calc1(mid+,rt<<|,A,B,C);
  78. if(calc1(mid+,rt<<|,A,B,C)>=mr) return qright(l,mid,rt<<,A,B,C);
  79. else return qright(mid+,r,rt<<|,A,B,C);
  80. }
  81. void build(int l,int r,int rt)
  82. {
  83. a[rt]=; b[rt]=c[rt]=;
  84. if(l==r){ mi[rt]=ma[rt]=v[l]; return; }
  85. int mid=(l+r)>>;
  86. build(l,mid,rt<<);
  87. build(mid+,r,rt<<|);
  88. pushup(rt);
  89. }
  90. void print(int l,int r,int rt,node *s)
  91. {
  92. if(l==r){ s[l].ans=mi[rt]; return; }
  93. int mid=(l+r)>>; pushdown(l,r,rt);
  94. print(l,mid,rt<<,s);
  95. print(mid+,r,rt<<|,s);
  96. }
  97. ll query(int x,int l,int r,int rt)
  98. {
  99. if(l==r) return mi[rt];
  100. int mid=(l+r)>>; pushdown(l,r,rt);
  101. if(x<=mid) return query(x,l,mid,rt<<);
  102. else return query(x,mid+,r,rt<<|);
  103. }
  104. }s;
  105.  
  106. int main()
  107. {
  108. scanf("%d%lld%lld",&n,&ml,&mr);
  109. char str[]; int i,j,l,r;
  110. for(i=;i<=n;i++)
  111. {
  112. scanf("%s",str);
  113. switch(str[])
  114. {
  115. case '+': p[i]=; break;
  116. case '-': p[i]=; break;
  117. case '*': p[i]=; break;
  118. case '@': p[i]=; break;
  119. }
  120. f[i]=gint();
  121. }
  122. scanf("%d",&m);
  123. for(i=;i<=m;i++) q[i].x=gint(),q[i].id=i;
  124. sort(q+,q+m+,cmp1);
  125. for(i=;i<=m;i++) v[i]=q[i].x;
  126. s.build(,m,);
  127. s.query(,,m,);
  128. for(i=;i<=n;i++)
  129. {
  130. switch(p[i])
  131. {
  132.  
  133. case :
  134. {
  135. l=s.qright(,m,,,,f[i]),r=m;
  136. if(l>) s.update(,l-,,m,,,,f[i]);
  137. if(l<=r) s.update(l,r,,m,,,,mr);
  138. break;
  139. }
  140. case :
  141. {
  142. l=s.qleft(,m,,,,-f[i]),r=m;
  143. if(l>) s.update(,l,,m,,,,ml);
  144. if(l<r) s.update(l+,r,,m,,,,-f[i]);
  145. break;
  146. }
  147. case :
  148. {
  149. l=s.qright(,m,,f[i],,),r=m;
  150. if(l>) s.update(,l-,,m,,f[i],,);
  151. if(l<=r) s.update(l,r,,m,,,,mr);
  152. break;
  153. }
  154. case :
  155. {
  156. l=s.qright(,m,,,f[i],),r=m;
  157. if(l>) s.update(,l-,,m,,,f[i],);
  158. if(l<=r) s.update(l,r,,m,,,,mr);
  159. break;
  160. }
  161.  
  162. }
  163.  
  164. }
  165. s.print(,m,,q);
  166. sort(q+,q+m+,cmp2);
  167. for(i=;i<=m;i++) printf("%lld\n",q[i].ans);
  168. return ;
  169. }

BZOJ 3878 [AHOI&JSOI2014]奇怪的计算器 (线段树)的更多相关文章

  1. BZOJ3878: [Ahoi2014&Jsoi2014]奇怪的计算器

    BZOJ3878: [Ahoi2014&Jsoi2014]奇怪的计算器 Description [故事背景] JYY有个奇怪的计算器,有一天这个计算器坏了,JYY希望你能帮助他写 一个程序来模 ...

  2. [BZOJ 3123] [SDOI 2013]森林(可持久化线段树+并查集+启发式合并)

    [BZOJ 3123] [SDOI 2013]森林(可持久化线段树+启发式合并) 题面 给出一个n个节点m条边的森林,每个节点都有一个权值.有两种操作: Q x y k查询点x到点y路径上所有的权值中 ...

  3. 2018.07.25 bzoj3878: [Ahoi2014&Jsoi2014]奇怪的计算器(线段树)

    传送门 线段树综合. 让我想起一道叫做siano" role="presentation" style="position: relative;"&g ...

  4. AHOI2014/JSOI2014 奇怪的计算器

    题目描述 题解: 考虑到经过一系列变化后小数不可能比大数大,我们可以用线段树维护区间修改. 重点是,每个节点都可以通过$a[i]=a[i]*t1+a0[i]*t2+t3$这个函数来表示,我们就可以把三 ...

  5. BZOJ.5110.[CodePlus2017]Yazid 的新生舞会(线段树/树状数组/分治)

    LOJ BZOJ 洛谷 又来发良心题解啦 \(Description\) 给定一个序列\(A_i\).求有多少个子区间,满足该区间众数出现次数大于区间长度的一半. \(n\leq5\times10^5 ...

  6. BZOJ.2653.[国家集训队]middle(可持久化线段树 二分)

    BZOJ 洛谷 求中位数除了\(sort\)还有什么方法?二分一个数\(x\),把\(<x\)的数全设成\(-1\),\(\geq x\)的数设成\(1\),判断序列和是否非负. 对于询问\(( ...

  7. BZOJ 5168 && Luogu P3740 [HAOI2014]贴海报 线段树~~

    据说某谷数据十分水...但幸好BZOJ上也过了...话说我记得讲课时讲的是奇奇怪怪的离散化..但现在突然觉得什么都可以线段树瞎搞了...QAQ 直接就是这个区间有没有被覆盖,被覆盖直接return: ...

  8. BZOJ 3307 雨天的尾巴 (树上差分+线段树合并)

    题目大意:给你一棵树,树上一共n个节点,共m次操作,每次操作给一条链上的所有节点分配一个权值,求所有节点被分配到所有的权值里,出现次数最多的权值是多少,如果出现次数相同就输出最小的. (我辣鸡bzoj ...

  9. [AHOI 2009] 维护序列(线段树模板题)

    1798: [Ahoi2009]Seq 维护序列seq Time Limit: 30 Sec  Memory Limit: 64 MB Description 老师交给小可可一个维护数列的任务,现在小 ...

随机推荐

  1. mongodb-主从复制

    1 主从复制: 一个概念,在sqlserver或者说是mysql也有 2 主从复制解决了哪些问题??? 读写压力:以前是一个mongodb去承载海量的读和写,这样的话终有瓶颈的.使用一主多从, 从服务 ...

  2. POJ 3528

    三维凸包 /* 增量法求凸包.选取一个四面体,同时把它各面的方向向量向外,增加一个点时,若该点与凸包上的某些面的方 向向量在同一侧,则去掉那些面,并使某些边与新增点一起连成新的凸包上的面. */ #i ...

  3. 【VC编程技巧】窗口☞3.6以渐变效果加载对话框

    平时我们常常能够看到非常多应用程序启动过程非常酷.什么百叶窗.渐变,各种效果,今天我们看一下怎样在程序中添加这样的效果. 一.演示样例展示: watermark/2/text/aHR0cDovL2Js ...

  4. WAS_集群部署应用遭遇ADMA0085E和ADMA0109W错误

    原创作品,出自 "深蓝的blog" 博客.深蓝的blog:http://blog.csdn.net/huangyanlong/article/details/47143431 近日 ...

  5. andoid电阻触摸移植

    这里我使用的是210的开发板 系统Android4.0.4 内核linux3.0.8 要用电阻屏一般都是使用tslib进行校准的 这里给个我在android上用的tslib 下载地址 http://d ...

  6. springAOP注解方式实现日志操作

    通过自定义注解调用方法执行日志存储: package com.zktx.platform.log2; import java.lang.reflect.Method; import java.util ...

  7. Adding a model

    https://docs.asp.net/en/latest/tutorials/first-mvc-app/adding-model.html Adding data model classes I ...

  8. 饭卡(hdoj--2546--背包)

    饭卡 Time Limit: 5000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) Total Submiss ...

  9. HUdson2092整数解

    2019-05-17 16:04:37 加油,坚持就是胜利,fightting m / i的情况,i可能等于0 #include <bits/stdc++.h> using namespa ...

  10. logging (日志) 模块

    本文源自景女神 函数式简单配置 import logging logging.debug('debug message') logging.info('info message') logging.w ...