【线段树多符号区间更新】HDU
来源:互联网 发布:mac brew mongodb 编辑:程序博客网 时间:2024/06/08 01:33
Problem Description
输入n,m。给你长度为n的数组,初始化为0。接下里有m行操作:
(1)”1 x y c”,代表 把区间 [x,y] 上的值全部加c(2)”2 x y c”,代表 把区间 [x,y] 上的值全部乘以c
(3)”3 x y c” 代表 把区间 [x,y]上的值全部赋值为c
(4)”4 x y p” 代表 求区间 [x,y] 上值的p次方和1<=p<=3
思路:
参考了一个我觉得很好的博客,但是有点不足的是,它的立方和那里错了
链接:http://www.cnblogs.com/GBRgbr/archive/2013/08/13/3254442.html。建议在敲的时候先别取mod,这样代码会清晰特别特别多。等敲好了,样例过了。在取模,这样就不会乱了,思路清晰还是很好敲的。
#include<bits/stdc++.h>using namespace std;#define lson root<<1#define rson root<<1|1#define MID int mid = (l + r) / 2#define N 100000#define mod 10007int sum[3][N<<2], flag[2][N<<2];//sum[0]-[2]分别代表一次,二次,三次方后的和。//flag[0]标记+了多少,flag[1]标记乘了多少void build(int root, int l, int r)//初始化{ flag[0][root] = 0; flag[1][root] = 1;//乘1还是本身 sum[0][root] = sum[1][root] = sum[2][root] = 0; if(l == r) return; MID; build(lson, l, mid); build(rson, mid + 1, r);}void Merge(int root, int l, int r)//归并和{ for(int i = 0; i < 3; i++) { sum[i][root] = (sum[i][lson] + sum[i][rson]) % mod; }}void add(int root, int l, int r, int c)//区间l-r都加c{ if(c){ int s0 = sum[0][root], s1 = sum[1][root]; //这些公式 纸上推一推就出来了 sum[0][root] = (s0 + ((r-l+1)%mod * c) % mod) % mod; //取掉mod后就特别清晰 s0+(r-l+1)*c sum[1][root] = (s1 + ((2*c)%mod * s0)%mod + ((((r-l+1)%mod*c)%mod)*c%mod)%mod) % mod; //s1+(2*c)*s0+(r-l+1)*c*c sum[2][root] = (sum[2][root] + (3*c%mod * s1)%mod + ((3*c%mod * c)%mod * s0)%mod + ((((r-l+1)%mod * c)%mod * c)%mod * c)%mod)%mod; //sum[2][root]+3*c*s1+3*c*c*s0+(r-l+1)*c*c*c } return;}void multi(int root, int l, int r, int v)//区间l-r都乘v{ if(v != 1){//不是1才乘,乘法就特别简单了。 int x = v; sum[0][root] *= x;// 乘了x一次方 sum[0][root] %= mod; x *= v; x %= mod; sum[1][root] *= x;// 乘了x二次方 sum[1][root] %= mod; x *= v; x %= mod; sum[2][root] *= x;// 乘了x立方 sum[2][root] %= mod; } return;}void pushdown(int root, int l, int r)//先乘法后加法。{ MID; if(flag[1][root] != 1) { flag[1][lson] *= flag[1][root]; flag[1][lson] %= mod; flag[1][rson] *= flag[1][root]; flag[1][rson] %= mod; flag[0][lson] *= flag[1][root]; flag[0][lson] %= mod; flag[0][rson] *= flag[1][root]; flag[0][rson] %= mod; multi(lson, l, mid, flag[1][root]); multi(rson, mid + 1, r, flag[1][root]); flag[1][root] = 1; } if(flag[0][root] != 0) { flag[0][lson] += flag[0][root]; flag[0][lson] %= mod; flag[0][rson] += flag[0][root]; flag[0][rson] %= mod; add(lson, l, mid, flag[0][root]); add(rson, mid + 1, r, flag[0][root]); flag[0][root] = 0; } return;}void updata(int root, int l, int r, int ul, int ur, int v, int ok){ if(ul <= l && r <= ur) { if(ok == 1)//区间加 { flag[0][root] += v; flag[0][root] %= mod; add(root, l, r, v);//更新sum } else if(ok == 2)//区间乘 { flag[0][root] *= v;//将区间加更新,这样pushdown的时候就先乘后加 flag[0][root] %= mod; flag[1][root] *= v; flag[1][root] %= mod; multi(root, l, r, v);//更新sum } else//区间全部赋值为v { flag[0][root] = v; flag[1][root] = 0;//为0,因为下面的都没用了。pushdown的时候可以更新掉。 multi(root, l, r, 0);//先乘 add(root, l, r, v);//再加 } return; } pushdown(root, l, r); MID; if(ul <= mid) updata(lson, l, mid, ul, ur, v, ok); if(ur > mid) updata(rson, mid + 1, r, ul, ur, v, ok); Merge(root, l, r);}int query(int root, int l, int r, int ul, int ur, int p){ if(ul <= l && r <= ur) { return sum[p-1][root];//看p就几次方的和 } pushdown(root, l, r); MID; int red = 0; if(ul <= mid) red += query(lson, l, mid, ul, ur, p) % mod; if(ur > mid) red += query(rson, mid + 1, r, ul, ur, p) % mod; return red;}int main(){ int n, m, ok, ul, ur, v; while(~scanf("%d %d", &n, &m)) { if(!n && !m) break; build(1, 1, n); while(m--) { scanf("%d %d %d %d", &ok, &ul, &ur, &v); if(ok == 4) { printf("%d\n", query(1, 1, n, ul, ur, v) % mod); } else { updata(1, 1, n, ul, ur, v, ok); } } }}
阅读全文
0 0
- 【线段树多符号区间更新】HDU
- HDU 1698 区间更新线段树
- hdu 3308 线段树 区间更新 LICS
- HDU 3308 LCIS 线段树区间更新
- hdu 4578 Transformation [线段树 区间更新]
- hdu 1698 线段树区间更新
- hdu 3308 线段树区间更新
- hdu 2795 线段树,区间更新求补值
- HDU 1698 【线段树区间更新】
- HDU 1698(线段树区间更新)
- hdu 1698 线段树 区间更新
- HDU 1698 线段树区间更新模板
- HDU 1698(线段树 区间更新)
- HDU 4578(线段树区间更新)
- hdu 1698 线段树 区间更新
- HDU 4893(线段树区间更新)
- HDU 1698(线段树区间更新)
- hdu 3577(线段树区间更新)
- rf报错集锦
- Caused by: org.apache.catalina.LifecycleException: A child container failed
- 为自己做的小计划 (电影类)-2
- 单调递增最长子序列
- DES加密解密
- 【线段树多符号区间更新】HDU
- hibernate增删查改
- 巴什博奕
- Bootstrap3.3 动态添加和关闭 tab的方案
- 深度学习路线图参考
- 五大常用算法基本介绍
- ANGEL:一个新型的分布式机器学习系统
- Linux(rad hat)基础知识
- 判断模拟器是否连网 没网进入连接中