传送门

终于过了这道题。。

要注意标记之间的影响,和add操作时更新求和的顺序。

same 区间每个数设置为x标记

mult  区间每个数乘x标记

add  区间每个数加x标记

①:当打same标记时,mult标记和add标记就没用了,要初始化。

②:当打mult标记时,add标记也要乘相应的值。

---------------求和可以递推过来---------------

1次方求和就正常求和

即:sum1[rt]=sum1[rt]+(r-l+1)*val;

2次方 可以由 (x+val)= x2+val2+2*x*val

即:sum2[rt]=sum2[rt]+2*sum1[rt]*val+(r-l+1)*val*val;

3次方 可以由 (x+val)= x3+val3+3*x2*val+3*x*val2

即:sum3[rt]=sum3[rt]+(r-l+1)*val*val*val+3*sum2[rt]*val+3*sum1[rt]*val*val;

再次注意  add求和要按照sum3,sum2, sum1的顺序!

算是又对取模有了一点了解。。

a*b*c*d  取模为  (a*b%mod) * (c*d%mod) %mod

a+b*c*d+3*a*b*c*d  取模为 (a + (b*c)%mod*d + 3*((a*b)%mod)*((c*d)%mod)%mod)%mod

 #include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int mod=;
const int maxx=; ll add[maxx<<],mult[maxx<<],same[maxx<<];
ll sum1[maxx<<],sum2[maxx<<],sum3[maxx<<]; int n,m,sum; void pushup(int rt) {
sum1[rt]=(sum1[rt<<]+sum1[rt<<|])%mod;
sum2[rt]=(sum2[rt<<]+sum2[rt<<|])%mod;
sum3[rt]=(sum3[rt<<]+sum3[rt<<|])%mod;
} void build(int l,int r,int rt) {
add[rt]=same[rt]=;
mult[rt]=;
if(l==r) {
sum1[rt]=sum2[rt]=sum3[rt]=;
return;
}
int mid=(l+r)>>;
build(l,mid,rt<<);
build(mid+,r,rt<<|);
pushup(rt);
} void pushdown(int rt,int len) { //下传标记
if(same[rt]) {
sum1[rt<<]=(len-(len>>))*same[rt]%mod;
sum1[rt<<|]=(len>>)*same[rt]%mod;
sum2[rt<<]=((len-(len>>))*same[rt]%mod)*same[rt]%mod;
sum2[rt<<|]=((len>>)*same[rt]%mod)*same[rt]%mod;
sum3[rt<<]=((len-(len>>))*same[rt]%mod)*(same[rt]*same[rt]%mod)%mod;
sum3[rt<<|]=((len>>)*same[rt]%mod)*(same[rt]*same[rt]%mod)%mod;
same[rt<<]=same[rt<<|]=same[rt];
add[rt<<]=add[rt<<|]=; //也需要改变
mult[rt<<]=mult[rt<<|]=; //也需要改变
same[rt]=;
}
if(mult[rt]!=) {
mult[rt<<]=mult[rt<<]*mult[rt]%mod;
mult[rt<<|]=mult[rt<<|]*mult[rt]%mod;
add[rt<<]=add[rt<<]*mult[rt]%mod; //改变
add[rt<<|]=add[rt<<|]*mult[rt]%mod; //改变
sum1[rt<<]=sum1[rt<<]*mult[rt]%mod;
sum1[rt<<|]=sum1[rt<<|]*mult[rt]%mod;
sum2[rt<<]=(sum2[rt<<]*mult[rt]%mod)*mult[rt]%mod;
sum2[rt<<|]=(sum2[rt<<|]*mult[rt]%mod)*mult[rt]%mod;
sum3[rt<<]=(sum3[rt<<]*mult[rt]%mod)*(mult[rt]*mult[rt]%mod)%mod;
sum3[rt<<|]=(sum3[rt<<|]*mult[rt]%mod)*(mult[rt]*mult[rt]%mod)%mod;
mult[rt]=;
}
if(add[rt]) {
add[rt<<]=(add[rt<<]+add[rt])%mod;
add[rt<<|]=(add[rt<<|]+add[rt])%mod;
sum3[rt<<]=(sum3[rt<<]+*sum2[rt<<]*add[rt]%mod+*(sum1[rt<<]*add[rt]%mod)*add[rt]%mod+(add[rt]*add[rt]%mod)*(add[rt]*(len-(len>>))%mod))%mod;
sum3[rt<<|]=(sum3[rt<<|]+*sum2[rt<<|]*add[rt]%mod+*(sum1[rt<<|]*add[rt]%mod)*add[rt]%mod+(add[rt]*add[rt]%mod)*(add[rt]*(len>>)%mod))%mod;
sum2[rt<<]=(sum2[rt<<]+*sum1[rt<<]*add[rt]%mod+(add[rt]*add[rt]%mod)*(len-(len>>))%mod)%mod;
sum2[rt<<|]=(sum2[rt<<|]+*sum1[rt<<|]*add[rt]%mod+(add[rt]*add[rt]%mod)*(len>>)%mod)%mod;
sum1[rt<<]=(sum1[rt<<]+(len-(len>>))*add[rt]%mod)%mod;
sum1[rt<<|]=(sum1[rt<<|]+(len>>)*add[rt]%mod)%mod;
add[rt]=;
}
} void updata(int L,int R, int val,int op,int l,int r,int rt) {
if(L<=l&&R>=r) {
if(op==) {
same[rt]=val;
mult[rt]=; //改变
add[rt]=; //改变
sum1[rt]=(r-l+)*val%mod;
sum2[rt]=((r-l+)*val%mod)*val%mod;
sum3[rt]=((r-l+)*val%mod)*(val*val%mod)%mod;
} else if(op==) {
mult[rt]=mult[rt]*val%mod;
add[rt]=add[rt]*val%mod; //改变
sum1[rt]=sum1[rt]*val%mod;
sum2[rt]=(sum2[rt]*val%mod)*val%mod;
sum3[rt]=(sum3[rt]*val%mod)*(val*val%mod)%mod;
} else if(op==) {
add[rt]=(add[rt]+val)%mod;
sum3[rt]=(sum3[rt]+*sum2[rt]*val%mod+*(sum1[rt]*val%mod)*val%mod+(((r-l+)*val%mod)*(val*val%mod)%mod))%mod;
sum2[rt]=(sum2[rt]+*sum1[rt]*val%mod+((r-l+)*val%mod)*val%mod)%mod;
sum1[rt]=(sum1[rt]+(r-l+)*val%mod)%mod;
}
return;
}
pushdown(rt,r-l+);
int mid=(l+r)>>;
if(L<=mid) updata(L,R,val,op,l,mid,rt<<);
if(R>mid) updata(L,R,val,op,mid+,r,rt<<|);
pushup(rt);
} ll query(int L,int R,int val,int l,int r,int rt) {
if(L<=l&&R>=r) {
if(val==) {
return sum1[rt]%mod;
} else if(val==) {
return sum2[rt]%mod;
} else return sum3[rt]%mod;
}
ll sum=;
pushdown(rt,r-l+);
int mid=(l+r)>>;
if(L<=mid) sum=(sum+query(L,R,val,l,mid,rt<<))%mod;
if(R>mid) sum=(sum+query(L,R,val,mid+,r,rt<<|))%mod;
return sum;
} int main() {
while(~scanf("%d%d",&n,&m)) {
if(n==&&m==) break;
build(,n,);
while(m--) {
int op,x,y,val;
scanf("%d%d%d%d",&op,&x,&y,&val);
if(op==) {
printf("%lld\n",query(x,y,val,,n,));
}
else updata(x,y,val,op,,n,);
}
}
}

HDU4578 Transformation (多操作线段树)的更多相关文章

  1. COGS 2638. 数列操作ψ 线段树

    传送门 : COGS 2638. 数列操作ψ 线段树 这道题让我们维护区间最大值,以及维护区间and,or一个数 我们考虑用线段树进行维护,这时候我们就要用到吉司机线段树啦 QAQ 由于发现若干次an ...

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

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

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

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

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

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

  5. BZOJ 1858: [Scoi2010]序列操作( 线段树 )

    略恶心的线段树...不过只要弄清楚了AC应该不难.... ---------------------------------------------------------------- #inclu ...

  6. 【bzoj1858】[Scoi2010]序列操作 线段树区间合并

    题目描述 lxhgww最近收到了一个01序列,序列里面包含了n个数,这些数要么是0,要么是1,现在对于这个序列有五种变换操作和询问操作: 0 a b 把[a, b]区间内的所有数全变成0 1 a b ...

  7. 【BZOJ2962】序列操作 线段树

    [BZOJ2962]序列操作 Description 有一个长度为n的序列,有三个操作1.I a b c表示将[a,b]这一段区间的元素集体增加c,2.R a b表示将[a,b]区间内所有元素变成相反 ...

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

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

  9. BZOJ 4034 [HAOI2015]树上操作 线段树+树剖或dfs

    题意 直接照搬原题面 有一棵点数为 N 的树,以点 1 为根,且树点有边权.然后有 M 个 操作,分为三种: 操作 1 :把某个节点 x 的点权增加 a . 操作 2 :把某个节点 x 为根的子树中所 ...

随机推荐

  1. jQuery实现contains方法不区分大小写的方法教程

    jQuery.expr[':'].Contains = function(a, i, m){ return jQuery(a).text().toUpperCase() .indexOf(m[3].t ...

  2. 2016.9.3初中部上午NOIP普及组比赛总结

    2016.9.3初中部上午NOIP普及组比赛总结 链接:https://jzoj.net/junior/#contest/home/1339 这次真爽,拿了个第四!(我还被班主任叫过去1小时呢!) 进 ...

  3. 【JZOJ2288】【BZOJ1898】【luoguP2579】沼泽鳄鱼

    description 潘塔纳尔沼泽地号称世界上最大的一块湿地,它地位于巴西中部马托格罗索州的南部地区.每当雨季来临,这里碧波荡漾.生机盎然,引来不少游客. 为了让游玩更有情趣,人们在池塘的中央建设了 ...

  4. MySQL其他和备份

    目录 事务 存储引擎 InnoDB存储引擎 数据存储形式 锁的粒度 事务 数据的存储特点 MyISAM存储引擎 数据存储形式 锁的粒度 事务 数据的存储特点 其他 对比与选择 视图 触发器 存储过程 ...

  5. 洛谷 NOIP提高组模拟赛 Day1

    传送门 ## $T1$ 一道结论题,设原来A队能力最大的是x,那么A队的选择方案就是$2^{x-1}$,B队的选择方案就是$(2^{n-x}-1)$种,因为不能不选.其中$1\leq x\leq n$ ...

  6. L2-006 树的遍历 (层序遍历)

    根据访问根节点与左右子树的先后顺序,二叉树一般有三种遍历方式:先序遍历.中序遍历和后序遍历. 只要给定中序遍历序列与先序或后序中的一种,可以还原二叉树结构.学习数据结构课程时,一直都只会手动构建还原二 ...

  7. 阿里云服务器(一)——Nodejs环境配置

    最近在阿里云上买了一个轻量应用服务器,想着用来学习一下Nodejs. 64位 配置Nodejs环境: 参考:https://www.runoob.com/nodejs/nodejs-install-s ...

  8. 解决Couldn't resolve host 'mirrorlist.centos.org

    这个错误引起主要是因为环境读取不到yun引起的可以考虑/etc/sysconfig/network-scripts/ifcfg-eth0 配置出错导致网络不通.或者/etc/resolv.conf的D ...

  9. Sublime text3 代码格式化插件vue

    同事用的windows的sublime轻量级容易上手.我们现在强制eslint规范.我们就需要安装这个格式化代码的插件"html-css-js-prettify" 使用 Subli ...

  10. python 日记 day4

    1.为何数据要分类 数据是用来表示状态的,不同的状态应该用不同类型的数据来表示. 2.数据类型 数字 字符串 列表 元组 字典 集合 列表:列表相比于字符串,不仅可以储存不同的数据类型,而且可以储存大 ...