BZOJ_1798_&_Codevs_2216_[AHOI_2009]_行星序列_(线段树)
描述
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]_行星序列_(线段树)的更多相关文章
- 【wikioi】2216 行星序列(线段树)
http://wikioi.com/problem/2216/ 这题太让我感动了QAQ,让我找到了我一直以来写线段树的错误!!!! 就是,pushdown一定要放在最前面!要不然顺序会错.也就是说,当 ...
- 【题解】P4247 [清华集训]序列操作(线段树修改DP)
[题解]P4247 [清华集训]序列操作(线段树修改DP) 一道神仙数据结构(DP)题. 题目大意 给定你一个序列,会区间加和区间变相反数,要你支持查询一段区间内任意选择\(c\)个数乘起来的和.对1 ...
- BZOJ_1018_[SHOI2008]_交通堵塞traffic_(线段树)
描述 http://www.lydsy.com/JudgeOnline/problem.php?id=1018 \(2*n\)的距形,起初没有边相连,之后有三种操作: 1.加边. 2.删边. 3.询问 ...
- BZOJ 1835: [ZJOI2010]base 基站选址 [序列DP 线段树]
1835: [ZJOI2010]base 基站选址 题目描述 有N个村庄坐落在一条直线上,第i(i>1)个村庄距离第1个村庄的距离为Di.需要在这些村庄中建立不超过K个通讯基站,在第i个村庄建立 ...
- [AHOI 2009] 维护序列(线段树模板题)
1798: [Ahoi2009]Seq 维护序列seq Time Limit: 30 Sec Memory Limit: 64 MB Description 老师交给小可可一个维护数列的任务,现在小 ...
- 【BZOJ-2962】序列操作 线段树 + 区间卷积
2962: 序列操作 Time Limit: 50 Sec Memory Limit: 256 MBSubmit: 678 Solved: 246[Submit][Status][Discuss] ...
- 【BZOJ-1858】序列操作 线段树
1858: [Scoi2010]序列操作 Time Limit: 10 Sec Memory Limit: 64 MBSubmit: 1961 Solved: 991[Submit][Status ...
- hdu 4521 小明系列问题——小明序列(线段树 or DP)
题目链接:hdu 4521 本是 dp 的变形,却能用线段树,感觉好强大. 由于 n 有 10^5,用普通的 dp,算法时间复杂度为 O(n2),肯定会超时.所以用线段树进行优化.线段树维护的是区间内 ...
- HDU 4521-小明序列(线段树好题)
题意: n个数字的序列,求各数位置间隔大于d的最长上升子序列 分析: 最基本的dp但是数据量大O(n^2)肯定超时 前dp[i]为的最长上升子序列是由前dp[1]---dp[i-d-1]符合条件的最大 ...
随机推荐
- windows下能读写linux分区的软件 转
1. ext2ifs 这个工具与explore2fs都是John Newbigin使用Delphi写的,explore2fs Copyright (C) 2000,Ext2IFS v0.3 Copyr ...
- 如何使用SC命令添加删除服务
1.如何删除服务 cmd然后再输入 sc delete "服务名称" 后,回车,双引号必须为英文符号. 2.添加服务 sc create ServiceName binPath= ...
- O-C相关-09-id 类型与应用
09-id 类型与应用 1, 使用 NSObject 访问子类对象方法 代码在编辑的时候, Xcode 会实时检查语法情况. 如果调用某个对象的方法, 在声明中没有该方法的声明, 那么就会报错. 但是 ...
- javascript函数 第14节
<html> <head> <title>function</title> </head> <body> 1.函数形式<b ...
- HDU 1175 连连看(BFS)
连连看 Time Limit: 20000/10000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others)Total Submi ...
- What are TCHAR, WCHAR, LPSTR, LPWSTR, LPCTSTR (etc.)?
转自: http://www.codeproject.com/Articles/76252/What-are-TCHAR-WCHAR-LPSTR-LPWSTR-LPCTSTR-etc 解释的超详细!! ...
- Python3 基础
Hello world 在文本编辑器中,键入python执行代码,保存文件为hello.py print('hello, world') 注意print前面不要有任何空格.然后,选择一个目录,例如C: ...
- Jquery EasyUI中treegrid的中右键菜单和一般按钮同时绑定事件时的怪异事件
做个项目使用jquery easyui来做前端,也许是对此不是很熟悉,总是发现一些不可理解的事件. 主要源代码如下: <script type="text/javascript&qu ...
- [DevExpress][TreeList]节点互斥
关键代码: /// <summary> /// 节点互斥同步 /// 说明 /// eg: ///TreeListNode _node = e.Node; ///_node.SyncMut ...
- jquery插件----文件上传uploadfile
使用了一款jquery上传的插件,ajax上传,可以显示上传的进度,高可配性,简要记录. 插件地址http://hayageek.com/docs/jquery-upload-file.php git ...