Transformation

Time Limit: 15000/8000 MS (Java/Others)    Memory Limit: 65535/65536 K (Java/Others)
Total Submission(s): 9392    Accepted Submission(s): 2408

Problem Description
Yuanfang is puzzled with the question below: 
There are n integers, a1, a2, …, an. The initial values of them are 0. There are four kinds of operations.
Operation 1: Add c to each number between ax and ay inclusive. In other words, do transformation ak<---ak+c, k = x,x+1,…,y.
Operation 2: Multiply c to each number between ax and ay inclusive. In other words, do transformation ak<---ak×c, k = x,x+1,…,y.
Operation 3: Change the numbers between ax and ay to c, inclusive. In other words, do transformation ak<---c, k = x,x+1,…,y.
Operation 4: Get the sum of p power among the numbers between ax and ay inclusive. In other words, get the result of axp+ax+1p+…+ay p.
Yuanfang has no idea of how to do it. So he wants to ask you to help him. 
 
Input
There are no more than 10 test cases.
For each case, the first line contains two numbers n and m, meaning that there are n integers and m operations. 1 <= n, m <= 100,000.
Each the following m lines contains an operation. Operation 1 to 3 is in this format: "1 x y c" or "2 x y c" or "3 x y c". Operation 4 is in this format: "4 x y p". (1 <= x <= y <= n, 1 <= c <= 10,000, 1 <= p <= 3)
The input ends with 0 0.
 
Output
For each operation 4, output a single integer in one line representing the result. The answer may be quite large. You just need to calculate the remainder of the answer when divided by 10007.
 
Sample Input
5 5
3 3 5 7
1 2 4 4
4 1 5 2
2 2 5 8
4 3 5 3
0 0
 
Sample Output
307
7489
题意:有4种操作,区间加,区间乘,区间修改以及区间幂之和。
题解:区间加==(mul==1,add==x) 区间乘==(mul==x,add==0)区间修改==(mul==0,add==x)区间幂通过展开式转化为区间乘和加,lazy标记用来标记当前点已经被更新过,pushdown(rt)用于更新子节点
 #include<bits/stdc++.h>
using namespace std;
#define debug(x) cout<<"["<<#x<<"]"<<" is "<<x<<endl
#define forp(x) for(int i=1;i<=x;i++)
#define scai(x) scanf("%d",&x)
#define scal(x) scanf("%lld",&x)
#define pri(x) printf("%d\n",x)
#define prl(x) printf("%lld\n",x)
typedef long long ll;
const int maxn=1e5+;
const ll mod=1e4+;
struct node{
int l;
int r;
ll ad;
ll mu;
ll a[];
}N[maxn<<];
void pushup(int rt){
N[rt].a[]=N[rt<<].a[]+N[(rt<<)|].a[];
N[rt].a[]=N[rt<<].a[]+N[(rt<<)|].a[];
N[rt].a[]=N[rt<<].a[]+N[(rt<<)|].a[];
N[rt].mu%=mod;
N[rt].ad%=mod;
N[rt].a[]%=mod;
N[rt].a[]%=mod;
N[rt].a[]%=mod;
}
void pushdown(int rt){
if(N[rt].mu!=){
ll m=N[rt].mu;
N[rt].mu=;
N[rt<<].ad=N[rt<<].ad*m%mod;
N[(rt<<)|].ad=N[(rt<<)|].ad*m%mod;
N[rt<<].mu=N[rt<<].mu*m%mod;
N[(rt<<)|].mu=N[(rt<<)|].mu*m%mod;
N[rt<<].a[]=N[rt<<].a[]*m%mod;
N[rt<<].a[]=N[rt<<].a[]*m%mod*m%mod;
N[rt<<].a[]=N[rt<<].a[]*m%mod*m%mod*m%mod;
N[(rt<<)|].a[]=N[(rt<<)|].a[]*m%mod;
N[(rt<<)|].a[]=N[(rt<<)|].a[]*m%mod*m%mod;
N[(rt<<)|].a[]=N[(rt<<)|].a[]*m%mod*m%mod*m%mod;
}
if(N[rt].ad!=){
ll m=N[rt].ad;
N[rt].ad=;
N[rt<<].ad=N[rt<<].ad+m%mod;
N[(rt<<)|].ad=N[(rt<<)|].ad+m%mod;
N[rt<<].a[]=N[rt<<].a[]+m%mod*m%mod*m%mod*(N[rt<<].r-N[rt<<].l+)%mod+*m*N[rt<<].a[]%mod+*m%mod*m%mod*N[rt<<].a[]%mod;
N[rt<<].a[]%=mod;
N[rt<<].a[]=N[rt<<].a[]+m%mod*m%mod*(N[rt<<].r-N[rt<<].l+)%mod+*m*N[rt<<].a[]%mod;
N[rt<<].a[]%=mod;
N[rt<<].a[]=N[rt<<].a[]+m*(N[rt<<].r-N[rt<<].l+)%mod;
N[rt<<].a[]%=mod;
N[(rt<<)|].a[]=N[(rt<<)|].a[]%mod+m%mod*m%mod*m%mod*(N[(rt<<)|].r-N[(rt<<)|].l+)%mod+*m*N[(rt<<)|].a[]%mod+*m%mod*m%mod*N[(rt<<)|].a[]%mod;
N[(rt<<)|].a[]%=mod;
N[(rt<<)|].a[]=N[(rt<<)|].a[]%mod+m%mod*m%mod*(N[(rt<<)|].r-N[(rt<<)|].l+)%mod+*m*N[(rt<<)|].a[]%mod;
N[(rt<<)|].a[]%=mod;
N[(rt<<)|].a[]=N[(rt<<)|].a[]+m*(N[(rt<<)|].r-N[(rt<<)|].l+)%mod;
N[(rt<<)|].a[]%=mod;
}
}
void build(int L,int R,int rt){
N[rt].l=L;
N[rt].r=R;
N[rt].mu=;
N[rt].ad=;
if(L==R){
N[rt].a[]=;
N[rt].a[]=;
N[rt].a[]=;
return;
}
int mid=(L+R)/;
build(L,mid,rt<<);
build(mid+,R,(rt<<)|);
pushup(rt);
}
void update(int L,int R,int rt,int l1,int r1,ll add,ll mul){
N[rt].mu%=mod;
N[rt].ad%=mod;
N[rt].a[]%=mod;
N[rt].a[]%=mod;
N[rt].a[]%=mod;
if(l1<=L&&r1>=R){
if(mul!=){
ll m=mul;
N[rt].ad=N[rt].ad*m%mod;
N[rt].mu=N[rt].mu*m%mod;
N[rt].a[]=N[rt].a[]*m%mod;
N[rt].a[]=N[rt].a[]*m%mod*m%mod;
N[rt].a[]=N[rt].a[]*m%mod*m%mod*m%mod;
}
if(add!=){
ll m=add;
N[rt].ad=N[rt].ad+m%mod;
N[rt].a[]=N[rt].a[]+m%mod*m%mod*m%mod*(N[rt].r-N[rt].l+)%mod+*m*N[rt].a[]%mod+*m%mod*m%mod*N[rt].a[]%mod;
N[rt].a[]%=mod;
N[rt].a[]=N[rt].a[]+m%mod*m%mod*(N[rt].r-N[rt].l+)%mod+*m%mod*N[rt].a[]%mod;
N[rt].a[]%=mod;
N[rt].a[]=N[rt].a[]+m*(N[rt].r-N[rt].l+)%mod;
N[rt].a[]%=mod;
}
return;
}
pushdown(rt);
int mid=(L+R)/;
if(mid>=l1){
update(L,mid,rt<<,l1,r1,add,mul);
}
if(mid<r1){
update(mid+,R,(rt<<)|,l1,r1,add,mul);
}
pushup(rt);
}
ll query(int L,int R,int rt,int l1,int r1,int p){
N[rt].mu%=mod;
N[rt].ad%=mod;
N[rt].a[]%=mod;
N[rt].a[]%=mod;
N[rt].a[]%=mod;
if(l1<=L&&r1>=R){
return N[rt].a[p]%mod;
}
int mid=(L+R)/;
ll ak=;
pushdown(rt);
if(mid>=l1){
ak+=query(L,mid,rt<<,l1,r1,p);
}
if(mid<r1){
ak+=query(mid+,R,(rt<<)|,l1,r1,p);
} return ak%mod;
}
int main(){
int n,m;
scai(n);
scai(m);
while(n||m){
build(,n,);
forp(m){
ll a,b,c,d;
scal(a);
scal(b);
scal(c);
scal(d);
if(a==){
update(,n,,b,c,d,);
}
else if(a==){
update(,n,,b,c,,d);
}
else if(a==){
update(,n,,b,c,d,);
}
else{
prl(query(,n,,b,c,d));
}
}
scai(n);
scai(m);
}
return ;
}

[hdoj4578][多延迟标记的线段树]的更多相关文章

  1. HDU 1698 just a hook - 带有lazy标记的线段树(用结构体实现)

    2017-08-30 18:54:40 writer:pprp 可以跟上一篇博客做个对比, 这种实现不是很好理解,上一篇比较好理解,但是感觉有的地方不够严密 代码如下: /* @theme:segme ...

  2. HDU1698 just a Hook - 带有lazy标记的线段树

    2017-08-30 16:44:33 writer:pprp 上午刚刚复习了一下不带有lazy标记的线段树, 下午开始学带有lazy标记的线段树 这个是我看大佬代码敲的,但是出了很多问题, 这提醒我 ...

  3. 洛谷 1083 (NOIp2012) 借教室——标记永久化线段树 / 差分+二分

    题目:https://www.luogu.org/problemnew/show/P1083 听说线段树不标记永久化会T一个点. 注意mn记录的是本层以下.带上标记的min! #include< ...

  4. [HDU5306]Gorgeous Sequence(标记回收线段树)

    题意:维护一个序列,支持区间与一个数取min,询问区间最大,询问区间和(序列长度<=1e6) 分析: http://www.shuizilong.com/house/archives/hdu-5 ...

  5. 带有lazy标记的线段树

    #include<bits/stdc++.h> using namespace std; ]; struct st{ int l,r,val,add; }tr[]; void build( ...

  6. Codeforces 444C 线段树 懒惰标记

    前天晚上的CF比赛div2的E题,很明显一个线段树,当时还在犹豫复杂度的问题,因为他是区间修改和区间查询,肯定是要用到懒惰标记. 然后昨天真的是给这道题跪了,写了好久好久,...我本来是写了个add标 ...

  7. 洛谷 P3373 【模板】线段树 2

    洛谷 P3373 [模板]线段树 2 洛谷传送门 题目描述 如题,已知一个数列,你需要进行下面三种操作: 将某区间每一个数乘上 xx 将某区间每一个数加上 xx 求出某区间每一个数的和 输入格式 第一 ...

  8. 【ACM/ICPC2013】线段树题目集合(一)

    前言:前一段时间在网上找了一个线段树题目列表,我顺着做了一些,今天我把做过的整理一下.感觉自己对线段树了解的还不是很深,自己的算法能力还要加强.光练代码能力还是不够的,要多思考.向队友学习,向大牛学习 ...

  9. 可持久化线段树——区间更新hdu4348

    和线段树类似,每个结点也要打lazy标记 但是lazy标记和线段树不一样 具体区别在于可持久化后lazy-tag不用往下传递,而是固定在这个区间并不断累加,变成了这个区间固有的性质(有点像分块的标记了 ...

随机推荐

  1. TCP调试助手,十六进制发送或者字符串形式发送的理解

    "无论创作还是欣赏,都是对法则和规律的逃逸,自由是艺术的源泉"-- 黑格尔 TCP调试助手中,在发送时可以选择十六进制发送或者字符串形式发送! 其实,两者最终调用的都是系统的soc ...

  2. 深度图转伪彩色图(python)

    kinect得到的深度图灰不拉几,人眼很难识别出其中的物体,感知深度的变化. 在做展示的时候,我们往往需要可视化,使用OpenCV的预定义的颜色映射来将灰度图像伪彩色化,在OpenCV中使用apply ...

  3. javaIO -- InputStream和OutStream

    一.简介 InputStream 和 OutputStream 对于字节流的输入和输出是作为协议的存在 所以有必要了解下这两个类提供出来的基本约定,这两个类是抽象类,而且基本上没什么实现,都是依赖于子 ...

  4. 基于requests模块的代理

    1.什么是代理? ​ 代理:将网络请求发送给代理服务器,通过代理服务器做中介,将请求转发给目标服务器并将响应返回,从而完成网络通信. 2.为什么使用代理? ​ 使用爬虫抓取批量资源时,在短时间内会对服 ...

  5. Unicode 编码 范围

    目录 所有字符 文字部分 ( U+0000 – U+007F) 基本拉丁字符 ( U+0080 – U+00FF) 增补拉丁字符集 1 ( U+0100 – U+017F) 拉丁字符扩展集 A ( U ...

  6. css 样式合集

    td换行: style="word-wrap:break-word;word-break:break-all;" 超长省略号: table { table-layout: fixe ...

  7. sql注入测试(4)--如何防止该类缺陷发生

    检查用户输入的合法性,确信输入的内容只包含合法的数据,数据检查应当在客户端和服务器端都执行之所以要执行服务器端验证,是为了弥补客户端验证机制脆弱的安全性.在客户端,攻击者完全有可能获得网页的源代码,修 ...

  8. 【转载】使用appium遇到的坑

    问题 1. error: Failed to start an Appium session, err was: Error: Requested a new session but one was ...

  9. Centos 在VM中设置静态ip

    cd /etc/sysconfig/network-scripts 然后代开第一个文件 一般是ifcfg-ens331)开始配置原来是这样的 修改/etc/sysconfig/network # Cr ...

  10. 关于微信小程序获取view的动态高度填坑

    wx.createSelectorQuery().select('#box').boundingClientRect(function (rect) { width = rect.width heig ...