老师说,你们暴力求除法也整不了多少次就归一了,暴力就好了(应该只有log(n)次)

于是暴力啊暴力,结果我归天了。

好吧,在各种题解的摧残下,我终于出了一篇巨好看(chou lou)代码(很多结构体党嫌丑)



那么具体除法怎么实现就是关键了

对于单个点或者区间内的数完全相同的区间,可以做成区间减法

因为除法会使数变小,而相同的数减小的量是相同的,

那么怎么判断区间内的数是否完全相同呢?

可以维护一个区间最小与区间最大,如果一个区间内最小数等于最大数,那么显然这个区间内所有数相等

区间最小与区间最大就不用说了吧?

然后暴力一波

  1. #include<bits/stdc++.h>
  2. #define ll long long
  3. using namespace std;
  4. ll sum[400101]={0}, minn[400101],maxx[400001]={0},add[400101]={0},a[401001];
  5. int n,m;
  6. void pushup(ll rt){
  7. sum[rt]=sum[rt<<1|1]+sum[rt<<1];
  8. minn[rt]=min(minn[rt<<1],minn[rt<<1|1]);
  9. maxx[rt]=max(maxx[rt<<1],maxx[rt<<1|1]);
  10. }
  11. inline ll Div(ll x, ll y) {//从样例分析出这道题是向下取整的除法
  12. return floor((double)x/y);
  13. }
  14. void build(ll l,ll r,ll rt){
  15. if(l==r){
  16. sum[rt]=a[l];
  17. minn[rt]=a[l];
  18. maxx[rt]=a[l];
  19. return ;
  20. }
  21. long long mid=(l+r)>>1;
  22. build(l,mid,rt<<1);
  23. build(mid+1,r,rt<<1|1);
  24. pushup(rt);
  25. }
  26. void pushdown(ll rt,ll ln,ll rn){
  27. if(add[rt]!=0){
  28. add[rt<<1]+=add[rt];
  29. add[rt<<1|1]+=add[rt];
  30. sum[rt<<1]+=add[rt]*ln;
  31. sum[rt<<1|1]+=add[rt]*rn;
  32. minn[rt<<1]+=add[rt];
  33. minn[rt<<1|1]+=add[rt];
  34. maxx[rt<<1]+=add[rt];
  35. maxx[rt<<1|1]+=add[rt];
  36. add[rt]=0;
  37. }
  38. }
  39. void update1(ll l,ll r,ll c,ll L,ll R,ll rt){
  40. if(l>=L&&r<=R){
  41. sum[rt]+=c*(r-l+1);
  42. add[rt]+=c;minn[rt]+=c;maxx[rt]+=c;
  43. return ;
  44. }
  45. ll mid=(l+r)>>1;
  46. pushdown(rt,mid-l+1,r-mid);
  47. if(L<=mid)update1(l,mid,c,L,R,rt<<1);
  48. if(R>mid)update1(mid+1,r,c,L,R,rt<<1|1);
  49. pushup(rt);
  50. }
  51. void update2(ll l,ll r,ll c,ll L,ll R,ll rt){//对于除法的暴力操作
  52. if (l >=L&&r<=R&&maxx[rt]-Div(maxx[rt],c)==minn[rt]-Div(minn[rt],c)){
  53. ll D=Div(maxx[rt],c)-maxx[rt];
  54. add[rt]+=D;maxx[rt]+=D;minn[rt]+=D;
  55. sum[rt]+=D*(r-l+1);
  56. return;
  57. }
  58. ll mid=(l+r)>>1;
  59. pushdown(rt,mid-l+1,r-mid);
  60. if(L<=mid)update2(l,mid,c,L,R,rt<<1);
  61. if(mid<R)update2(mid+1,r,c,L,R,rt<<1|1);
  62. pushup(rt);
  63. }
  64. ll query1(ll l,ll r,ll L,ll R,ll rt){
  65. if(l>=L&&r<=R){
  66. return sum[rt];
  67. }
  68. ll mid=(l+r)>>1;
  69. ll ans=0;
  70. pushdown(rt,mid-l+1,r-mid);
  71. if(L<=mid)ans+=query1(l,mid,L,R,rt<<1);
  72. if(R>mid)ans+=query1(mid+1,r,L,R,rt<<1|1);
  73. return ans;
  74. }
  75. ll query2(ll l,ll r,ll L,ll R,ll rt){
  76. if(l>=L&&r<=R){
  77. return minn[rt];
  78. }
  79. ll mid=(l+r)>>1;
  80. ll ans=1e18;
  81. pushdown(rt,mid-l+1,r-mid);
  82. if(L<=mid)ans=min(ans,query2(l,mid,L,R,rt<<1));
  83. if(R>mid)ans=min(ans,query2(mid+1,r,L,R,rt<<1|1));
  84. return ans;
  85. }
  86. int main(){
  87. scanf("%d%d",&n,&m);
  88. for(int i=0;i<n;i++)scanf("%lld",&a[i]);
  89. //memset(flag,1,sizeof(flag));
  90. build(0,n-1,1);
  91. while(m--){
  92. long long c,x,y,k;
  93. scanf("%lld%lld%lld",&c,&x,&y);
  94. if(c==1){scanf("%lld",&k);update1(0,n-1,k,x,y,1);}
  95. if(c==2){scanf("%lld",&k);update2(0,n-1,k,x,y,1);}
  96. if(c==4)printf("%lld\n",query1(0,n-1,x,y,1));
  97. if(c==3)printf("%lld\n",query2(0,n-1,x,y,1));
  98. }
  99. return 0;
  100. }

「雅礼集训 2017 Day1」市场 (线段树除法,区间最小,区间查询)的更多相关文章

  1. LOJ #6029. 「雅礼集训 2017 Day1」市场 线段树维护区间除法

    题目描述 从前有一个贸易市场,在一位执政官到来之前都是非常繁荣的,自从他来了之后,发布了一系列奇怪的政令,导致贸易市场的衰落. 有 \(n\) 个商贩,从\(0 \sim n - 1\) 编号,每个商 ...

  2. loj#6029. 「雅礼集训 2017 Day1」市场(线段树)

    题意 链接 Sol 势能分析. 除法是不能打标记的,所以只能暴力递归.这里我们加一个剪枝:如果区间内最大最小值的改变量都相同的话,就变成区间减. 这样复杂度是\((n + mlogn) logV\)的 ...

  3. 【loj6029】「雅礼集训 2017 Day1」市场 线段树+均摊分析

    题目描述 给出一个长度为 $n$ 的序列,支持 $m$ 次操作,操作有四种:区间加.区间下取整除.区间求最小值.区间求和. $n\le 100000$ ,每次加的数在 $[-10^4,10^4]$ 之 ...

  4. #6029. 「雅礼集训 2017 Day1」市场 [线段树]

    考虑到每次除法,然后加法,差距会变小,于是维护加法lazytag即可 #include <cstdio> #include <cmath> #define int long l ...

  5. [LOJ 6029]「雅礼集训 2017 Day1」市场

    [LOJ 6029] 「雅礼集训 2017 Day1」市场 题意 给定一个长度为 \(n\) 的数列(从 \(0\) 开始标号), 要求执行 \(q\) 次操作, 每次操作为如下四种操作之一: 1 l ...

  6. 【loj6029】「雅礼集训 2017 Day1」市场&&【uoj#228】基础数据结构练习题

    题解: 这两道题加上区间取min max应该算线段树几道比较不寻常的题目 其实也是挺好理解的 对于区间/d 显然在log次后就会等于0 而我们注意到如果区间中数都相等那么就可以一起除 也就是说每个区间 ...

  7. loj6029 「雅礼集训 2017 Day1」市场

    传送门:https://loj.ac/problem/6029 [题解] 考虑如果有一些近似连续的段 比如 2 2 2 3 3 3,考虑在除3意义下,变成0 0 0 1 1 1,相当于整体-2 又:区 ...

  8. 【LOJ6029】「雅礼集训 2017 Day1」市场(线段树裸题)

    点此看题面 大致题意: 维护序列,支持区间加法,区间除法(向下取整),区间求\(min\)和区间求和. 线段树维护区间除法 区间加法.区间求\(min\)和区间求和都是线段树基本操作,因此略过不提. ...

  9. 【loj6029】「雅礼集训 2017 Day1」市场

    题目 题意:四种操作,区间加法.区间除法(下取整).区间求最小值.区间求和. 第1.3.4个操作都是摆设,关键在于如何做区间除法. 很明显不能直接把区间的和做除法后向下取整,因为区间和可能会多凑出一个 ...

随机推荐

  1. oracle 的replace()

    1.查询所有员工的姓名,如果包含字母s,则用S替换. 2.查询所有员工姓名的前三个字符.

  2. 04 关于oracle的锁的级别以及介绍

    关于oracle的锁的级别以及介绍 oracle造成锁表的情况: 一.查看锁的对象视图:select object_id,session_id,locked_mode from v$locked_ob ...

  3. Rem实现自适应布局

    rem布局的目的是为了让我们可以用同一份代码,适应不同的移动终端(rem:就是css单位) 1.项目入口html文件<meta name="viewport" content ...

  4. 利用SoapUI 测试web service的一些问题总结

    总结两个利用SoapUI 测试web service的一些问题: 1.请求一个soap service 请求的时候:按照下面的配置输入请求地址后, 2.根据实际service接口的需要,传入相应的参数 ...

  5. json提取嵌套数据

    //数据 string html = "{\"code\":\"0000\",\"desc\":\"\",\& ...

  6. ASP.NET MVC4.0 后台获取不大前台传来的file

    <td>选择图片</td> <td> <input type="file" id="uploadImg" name=& ...

  7. angular-sanitize 插件的使用,获取带html标签的内容

    1,安装 angular-sanitize bower install angular-sanitize --save 引入到 html <script src="/bower_com ...

  8. 一条sql 执行查询列表 返回分页数据以及总数 totalCount

    SELECT ID,Name,Age,Addr,Tel,COUNT(1) OVER() AS totalFROM dbo.Student WHERE Age>22 ORDER BY id DES ...

  9. transform Vs Udf

    在鞋厂的第一个任务,拆表.需要把订单表按照开始日期和结束日期拆分成多条记录,挺新鲜的~ transform方式,使用到了python. (1)把hive表的数据传入,通过python按照日期循环处理, ...

  10. 面试乐融集团Python开发工程师有感

    这是笔者第一次面试,,乐融集团位于朝阳区朝阳公园的乐融大厦.是下午两点的笔面试,笔者是一点半到的,然后在里面等了会,开始笔试 笔试题并不是太难,就是考的比较宽,因为笔者是校招,所以笔试题出来了数据结构 ...