描述


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定义,在乘法的时候强制转换一下就好了.

 #include<cstdio>
#include<algorithm>
#define ll long long
#define lson 2*k
#define rson 2*k+1 const int maxn=1e5+;
int n,m,mod;
int w[maxn];
struct node { int l,r,x,f,p; }a[*maxn]; void build_tree(int l,int r,int k)
{
a[k].l=l; a[k].r=r; a[k].f=; a[k].p=;
if(l==r)
{
a[k].x=w[l];
return;
}
int mid=l+(r-l)/;
build_tree(l,mid,lson);
build_tree(mid+,r,rson);
a[k].x=(a[lson].x+a[rson].x)%mod;
} inline void cal(int k,int f,int p)
{
a[k].x=(int)((((ll)a[k].x*(ll)f)%mod+((ll)(a[k].r-a[k].l+)%mod)*(ll)p)%mod);
a[k].f=(int)(((ll)a[k].f*(ll)f)%mod);
a[k].p=(int)((((ll)a[k].p*(ll)f)%mod+p)%mod);
} inline void push_down(int k)
{
cal(lson,a[k].f,a[k].p);
cal(rson,a[k].f,a[k].p);
a[k].f=;
a[k].p=;
} void update(int l,int r,int k,int f,int p)
{
if(a[k].l==l&&a[k].r==r)
{
cal(k,f,p);
return;
}
if(a[k].f!=||a[k].p)
{
push_down(k);
}
int mid=a[k].l+(a[k].r-a[k].l)/;
if(r<=mid)
{
update(l,r,lson,f,p);
}
else if(l>mid)
{
update(l,r,rson,f,p);
}
else
{
update(l,mid,lson,f,p);
update(mid+,r,rson,f,p);
}
a[k].x=(a[lson].x+a[rson].x)%mod;
} int search(int l,int r,int k)
{
if(a[k].l==l&&a[k].r==r)
{
return a[k].x;
}
if(a[k].f!=||a[k].p)
{
push_down(k);
}
int mid=a[k].l+(a[k].r-a[k].l)/;
if(r<=mid)
{
return (search(l,r,lson)%mod);
}
else if(l>mid)
{
return (search(l,r,rson)%mod);
}
else
{
return ((search(l,mid,lson)+search(mid+,r,rson))%mod);
}
} int main()
{
#ifndef ONLINE_JUDGE
freopen("star.in","r",stdin);
freopen("star.out","w",stdout);
#endif
scanf("%d%d",&n,&mod); for(int i=;i<=n;i++)
{
scanf("%d",&w[i]);
}
build_tree(,n,);
scanf("%d",&m);
int qry,l,r,c;
for(int i=;i<=m;i++)
{
scanf("%d%d%d",&qry,&l,&r);
switch(qry)
{
case :
scanf("%d",&c);
c%=mod;
update(l,r,,c,);
break;
case :
scanf("%d",&c);
c%=mod;
update(l,r,,,c);
break;
case :
printf("%d\n",search(l,r,));
break;
}
}
#ifndef ONLINE_JUDGE
fclose(stdin);
fclose(stdout);
system("star.out");
#endif
return ;
}

BZOJ_1798_&_Codevs_2216_[AHOI_2009]_行星序列_(线段树)的更多相关文章

  1. 【wikioi】2216 行星序列(线段树)

    http://wikioi.com/problem/2216/ 这题太让我感动了QAQ,让我找到了我一直以来写线段树的错误!!!! 就是,pushdown一定要放在最前面!要不然顺序会错.也就是说,当 ...

  2. 【题解】P4247 [清华集训]序列操作(线段树修改DP)

    [题解]P4247 [清华集训]序列操作(线段树修改DP) 一道神仙数据结构(DP)题. 题目大意 给定你一个序列,会区间加和区间变相反数,要你支持查询一段区间内任意选择\(c\)个数乘起来的和.对1 ...

  3. BZOJ_1018_[SHOI2008]_交通堵塞traffic_(线段树)

    描述 http://www.lydsy.com/JudgeOnline/problem.php?id=1018 \(2*n\)的距形,起初没有边相连,之后有三种操作: 1.加边. 2.删边. 3.询问 ...

  4. BZOJ 1835: [ZJOI2010]base 基站选址 [序列DP 线段树]

    1835: [ZJOI2010]base 基站选址 题目描述 有N个村庄坐落在一条直线上,第i(i>1)个村庄距离第1个村庄的距离为Di.需要在这些村庄中建立不超过K个通讯基站,在第i个村庄建立 ...

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

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

  6. 【BZOJ-2962】序列操作 线段树 + 区间卷积

    2962: 序列操作 Time Limit: 50 Sec  Memory Limit: 256 MBSubmit: 678  Solved: 246[Submit][Status][Discuss] ...

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

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

  8. hdu 4521 小明系列问题——小明序列(线段树 or DP)

    题目链接:hdu 4521 本是 dp 的变形,却能用线段树,感觉好强大. 由于 n 有 10^5,用普通的 dp,算法时间复杂度为 O(n2),肯定会超时.所以用线段树进行优化.线段树维护的是区间内 ...

  9. HDU 4521-小明序列(线段树好题)

    题意: n个数字的序列,求各数位置间隔大于d的最长上升子序列 分析: 最基本的dp但是数据量大O(n^2)肯定超时 前dp[i]为的最长上升子序列是由前dp[1]---dp[i-d-1]符合条件的最大 ...

随机推荐

  1. MVC小系列(十四)【MVC+ZTree大数据异步树加载】

    ZTree是一个jquery的树插件可以异步加载 第一步定义一个标准的接口(指的是与ztree默认的数据元素保持一致) /// <summary> /// ZTree数据结构 /// &l ...

  2. 有理数类 Java BigInteger实现

    import java.math.BigInteger; public class Rational extends Number implements Comparable { private Bi ...

  3. JAVA中实现百分比

    import java.text.NumberFormat; public class TeachYou { public static void main(String[] args) { //这里 ...

  4. 分享一下个人的Vim配置文件

    强烈拥护开源精神,高举开源大旗,今天我就分享下我自己结合网上还有自己实际使用配的vimrc,可以给各位参考下,不要见笑哈,具体说明我在rc里写的也很详细,可以具体看下,也希望可以借这个机会能多认识认识 ...

  5. (jQuery 插件)封装容器的表单为json对象

    下面代码可以把一个页面容器中的表单元素封装成一个json对象. (function($){ $.fn.serializeObject=function(){ var inputs=$(this).fi ...

  6. 阻止CSS样式被缓存

    <link href="/stylesheet.css?<?php echo time(); ?>" rel="stylesheet" typ ...

  7. cmake 安装 mysql

    因为高版本mysql都用cmake安装,另外安装cluster版的mysql也必须通过cmake安装,所以学习cmake安装mysql很有必要. 今天我因为打算搭配一个mysql集群所以,在虚拟机上安 ...

  8. Python使用re实现计算器

    re 正则表达式 计算器 海瑞博客-学习python之路•2016-12-01•Python• 59•0•A+ A- re是一门小型语言 元字符 .      通配符除了\n ^     以什么开始的 ...

  9. 进位位(carry)与溢出位(overflow)的区别

    处理器内部以补码表示有符号数,8个二进制位能够表达的整数范围是:+127 ~ -128,16位表达的范围是:+32767 ~ -32768.如果运算结果超出了这个范围,就是产生了溢出:有溢出,说明有符 ...

  10. 配置mybatis错误总结

    ### The error may exist in SQL Mapper Configuration ### Cause: org.apache.ibatis.builder.BuilderExce ...