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. springboot集成elk 三:springboot + Elasticsearch Rest-Client

    注:  该集成方式,对Elasticsearch无版本限制,但是需要自行封装请求,解析结果等. <dependency> <groupId>org.elasticsearch. ...

  2. vue A对象赋值给B对象,修改B属性会影响到A问题

    实际在vue中  this.A = this.B,没有进行深层赋值,只是把this.A的地址指向了与this.B相同的地址,所有对于A的修改会影响到B. 解决相互影响的思路是在this.A必须是新建的 ...

  3. [转帖]Oracle报错ORA-26563--当重命名表时碰到物化视图

    Oracle报错ORA-26563--当重命名表时碰到物化视图 https://www.toutiao.com/i6739137279115133447/ 原创 波波说运维 2019-09-26 00 ...

  4. [转帖]Greenplum :基于 PostgreSQL 的分布式数据库内核揭秘 (上篇)

    Greenplum :基于 PostgreSQL 的分布式数据库内核揭秘 (上篇) https://www.infoq.cn/article/3IJ7L8HVR2MXhqaqI2RA 学长的文章.. ...

  5. sql query skill

    https://www.w3resource.com/sqlite/sqlite-select-query-statement.php /* SELECT ChipID FROM "tb_X ...

  6. WUSTOJ 1246: 字符串排序(Java)

    1246: 字符串排序 题目   输入n(n<100)个字符串,每个字符串长度不超过1000,将他们按字典顺序输出.更过内容点击标题. 分析   Java中的ArrayList()可以比较方便的 ...

  7. Go语言学习笔记(7)——函数和方法

    Go语言中同时有函数和方法! 函数: go程序必须要包含一个main函数.main函数不能有任何参数和返回值! 1. 定义方法示例: func max(num1, num2 int) int { // ...

  8. [Vue]vue中路由重定向redirect

    1.重定向的地址不需要接收参数 const routes = [ { path: '/', redirect: '/index'}, { path: '/index', component: inde ...

  9. Docker多阶段构建实战(multi-stage builds)

    在编写Dockerfile构建docker镜像时,常遇到以下问题: RUN命令会让镜像新增layer,导致镜像变大,虽然通过&&连接多个命令能缓解此问题,但如果命令之间用到docker ...

  10. div上中下布局中间自适应

    需求1: 头尾固定高度,中间自适应 1.上部(header)Div高度固定100px,宽度100%: 2.下部(footer)Div高度固定100px,宽度100%: 3.中部(middle)DIV高 ...