描述


BZOJ: http://www.lydsy.com/JudgeOnline/problem.php?id=1798

Codevs: http://codevs.cn/problem/2216/

给出n和行星的质量,进行m次操作:

1.将[l,r]区间内所有行星质量*c.

2.将[l,r]区间内所有行星质量+c.

3.询问[l,r]区间内行星质量和.

分析


双标记线段树,多加一个乘法的标记.a[k]位置的标记表示的是要传给a[k]的子节点的值,乘法位置为a[k].f,加法为a[k].p,表示的是先乘后加.按照先乘后加的规定,当跟新值时,ax+b变为(ax+b)*c1+c2=axc1+bc1+c2=(axc1)+(bc1+c2),也就是标记向下传递(push_down)的时候,乘法位置要乘,加法位置要先乘后加.

之前一直wa,最后才发现数组没开够...

感觉好像把乘法转化为加法也能做...但没尝试.

注意:

1.最好在确保扔给函数的参数都是取过模的,这样不容易出错.

2.可以不用long long定义,在乘法的时候强制转换一下就好了.

  1 #include<cstdio>
  2 #include<algorithm>
  3 #define ll long long
  4 #define lson 2*k
  5 #define rson 2*k+1
  6
  7 const int maxn=1e5+5;
  8 int n,m,mod;
  9 int w[maxn];
 10 struct node { int l,r,x,f,p; }a[3*maxn];
 11
 12 void build_tree(int l,int r,int k)
 13 {
 14     a[k].l=l; a[k].r=r; a[k].f=1; a[k].p=0;
 15     if(l==r)
 16     {
 17         a[k].x=w[l];
 18         return;
 19     }
 20     int mid=l+(r-l)/2;
 21     build_tree(l,mid,lson);
 22     build_tree(mid+1,r,rson);
 23     a[k].x=(a[lson].x+a[rson].x)%mod;
 24 }
 25
 26 inline void cal(int k,int f,int p)
 27 {
 28     a[k].x=(int)((((ll)a[k].x*(ll)f)%mod+((ll)(a[k].r-a[k].l+1)%mod)*(ll)p)%mod);
 29     a[k].f=(int)(((ll)a[k].f*(ll)f)%mod);
 30     a[k].p=(int)((((ll)a[k].p*(ll)f)%mod+p)%mod);
 31 }
 32
 33 inline void push_down(int k)
 34 {
 35     cal(lson,a[k].f,a[k].p);
 36     cal(rson,a[k].f,a[k].p);
 37     a[k].f=1;
 38     a[k].p=0;
 39 }
 40
 41 void update(int l,int r,int k,int f,int p)
 42 {
 43     if(a[k].l==l&&a[k].r==r)
 44     {
 45         cal(k,f,p);
 46         return;
 47     }
 48     if(a[k].f!=1||a[k].p)
 49     {
 50         push_down(k);
 51     }
 52     int mid=a[k].l+(a[k].r-a[k].l)/2;
 53     if(r<=mid)
 54     {
 55         update(l,r,lson,f,p);
 56     }
 57     else if(l>mid)
 58     {
 59         update(l,r,rson,f,p);
 60     }
 61     else
 62     {
 63         update(l,mid,lson,f,p);
 64         update(mid+1,r,rson,f,p);
 65     }
 66     a[k].x=(a[lson].x+a[rson].x)%mod;
 67 }
 68
 69 int search(int l,int r,int k)
 70 {
 71     if(a[k].l==l&&a[k].r==r)
 72     {
 73         return a[k].x;
 74     }
 75     if(a[k].f!=1||a[k].p)
 76     {
 77         push_down(k);
 78     }
 79     int mid=a[k].l+(a[k].r-a[k].l)/2;
 80     if(r<=mid)
 81     {
 82         return (search(l,r,lson)%mod);
 83     }
 84     else if(l>mid)
 85     {
 86         return (search(l,r,rson)%mod);
 87     }
 88     else
 89     {
 90         return ((search(l,mid,lson)+search(mid+1,r,rson))%mod);
 91     }
 92 }
 93
 94 int main()
 95 {
 96 #ifndef ONLINE_JUDGE
 97     freopen("star.in","r",stdin);
 98     freopen("star.out","w",stdout);
 99 #endif
100     scanf("%d%d",&n,&mod);
101
102     for(int i=1;i<=n;i++)
103     {
104         scanf("%d",&w[i]);
105     }
106     build_tree(1,n,1);
107     scanf("%d",&m);
108     int qry,l,r,c;
109     for(int i=1;i<=m;i++)
110     {
111         scanf("%d%d%d",&qry,&l,&r);
112         switch(qry)
113         {
114             case 1:
115                 scanf("%d",&c);
116                 c%=mod;
117                 update(l,r,1,c,0);
118                 break;
119             case 2:
120                 scanf("%d",&c);
121                 c%=mod;
122                 update(l,r,1,1,c);
123                 break;
124             case 3:
125                 printf("%d\n",search(l,r,1));
126                 break;
127         }
128     }
129 #ifndef ONLINE_JUDGE
130     fclose(stdin);
131     fclose(stdout);
132     system("star.out");
133 #endif
134     return 0;
135 }

View Code

转载于:https://www.cnblogs.com/Sunnie69/p/5436371.html

BZOJ_1798__Codevs_2216_[AHOI_2009]_行星序列_(线段树)相关推荐

  1. 【BZOJ-1858】序列操作 线段树

    1858: [Scoi2010]序列操作 Time Limit: 10 Sec  Memory Limit: 64 MB Submit: 1961  Solved: 991 [Submit][Stat ...

  2. BZOJ1858 [Scoi2010]序列操作 线段树

    欢迎访问~原文出处--博客园-zhouzhendong 去博客园看该题解 题目传送门 - BZOJ1858 题意概括 lxhgww最近收到了一个01序列,序列里面包含了n个数,这些数要么是0,要么是1 ...

  3. Wannafly挑战赛22 D 整数序列 (线段树维护三角函数值)

    链接:https://ac.nowcoder.com/acm/contest/160/D 来源:牛客网 整数序列 时间限制:C/C++ 2秒,其他语言4秒 空间限制:C/C++ 262144K,其他语 ...

  4. HYSBZ - 1798 Seq 维护序列seq 线段树lazy标记

    传送门 这道题属实是线段树的道比刷题,又加又乘的,当然还可能会有乘除,阶乘等等可能的情况. 对于这道题,主要的一个就是怎么记录lazy标记,首先的话一个数组是肯定不行的,设乘的为lazy,加的为add ...

  5. [HNOI2016] 序列(线段树 + 莫队 + 倍增)

    problem luogu-P3246 心路历程+卡常历程+问题存疑 一直在想莫队的做法.发现左右指针的移动对应一段左/右端点固定的子序列,然后可以一个数代表一段相同的贡献. 就开始求 lsti,nx ...

  6. Wannafly挑战赛22 D-整数序列 (线段树)

    https://www.nowcoder.com/acm/contest/160/D 做法:用线段树维护,对于树上的每个叶子结点,维护一个复数结构体 cos(a[i] + sin(a[i])*i ,每 ...

  7. Luogu P2572 [SCOI2010]序列操作 线段树。。

    咕咕了...于是借鉴了小粉兔的做法ORZ... 其实就是维护最大子段和的线段树,但上面又多了一些操作....QWQ 维护8个信息:1/0的个数(sum),左/右边起1/0的最长长度(ls,rs),整段 ...

  8. Java_太阳系_行星模型_小游戏练习_详细注释

    1 //实现MyFrame--实现绘制窗口,和实现重写 重画窗口线程类 2 3 package cn.xiaocangtian.Test; 4 5 import java.awt.Frame; 6 i ...

  9. bzoj 2962 序列操作 线段树

    这个题卡常数.. 首先c比较小,所以可以考虑dp转移,对于合并子序列就直接枚举跨区间的就可以了 对于反转操作,要注意只有奇数位置才会变成相反数 对于增加操作,可以考虑抽象成组合数学问题: 对于(a1+ ...

最新文章

  1. c语言程序设计01,c语言程序设计01.doc
  2. php的引用变量与销毁机制
  3. IDEA 方法注释模板和类注释模板
  4. 制造业如何将工人师傅的隐性技能转化为显性知识?
  5. LV 旗下公司的识别算法: 4 秒鉴定假包,准确率达 99.1%
  6. 修正mysqlcc在MySQL 5.0上常报的 Table 'xxx' doesn't exist 错误
  7. ExtJS入门(08)窗口,按钮,输入框,
  8. 使用MAP文件快速定位程序崩溃代码行(转)
  9. [渝粤教育] 西南科技大学 微机原理与应用 在线考试复习资料(1)
  10. MySQL划重点-查询-条件
  11. JAVA之private修饰成员方法默认是final型的?
  12. 【TensorFlow】TensorFlow函数精讲之tf.nn.max_pool()和tf.nn.avg_pool()
  13. 新西兰计算机专业研究生一年,【新西兰计算机专业研究生】 - 教外新西兰留学网...
  14. 最好用的五大服装进销存管理软件,强推第一个
  15. 软件测试周刊(第37期):不能随便生气
  16. 第三章 心剑,有妹紫灵
  17. 安装infinity后主页始终显示百度页面?
  18. 魅族手机CUP浮点运算测试BUG
  19. 全系列毕业设计论文来了
  20. 英语六级口语 计算机,2020年5月英语六级口语惯用口语:计算机

热门文章

  1. Android高效开发:
  2. 如何用distinct消除重复记录的同时又能选取多个字段值?
  3. 看完这篇文章保你面试稳操胜券——React篇
  4. jquery --- 阻止表单默认的提交行为,标准化表单的数据
  5. [算法]不用第三个数交换2个数的位置
  6. 设计模式20——Mediator设计模式
  7. 微软系统修复工具(试用版)
  8. Oracle 数据库实例启动关闭过程
  9. 在Ubuntu桌面上显示我的电脑等图标
  10. Ti的DM368系列芯片的所有PDF资料汇总