自己写了一个带结构体的WA了7.8次 但是测了几组小数据都对。。感觉问题应该出在模运算那里。写完这波题解去对拍一下。

以后线段树绝不写struct!一般的struct都带上l,r 但是一条线段的长度确定的话,每一个节点的l,r都可以确定的,没必要用struct存上,如果不带上l,r那不是更没必要用结构体hhh

这道题有点坑的地方就是顺序问题

pushdown就是一个最大的难点

change表示改数字 add表示加上数字 multiply表示乘以一个数字

正确的方法应该是 先change 再multiply 再add

先看multiply和add的关系

现在p的数字是x 先add a 然后multiply b 就会变成 b*(x+a)假如我们采用保留括号的方法 那么先multiply后add会变得异常麻烦

因为先multiply后add是b*x+a 再搞出一个括号来会有误差 所以我们选择不保留括号 如果先add后multiply的话 add的数字就乘上multiply的数字

这样就不会有误差 所以在pushdown操作里面 我们就先multiply后add 因为多项式是bx+a嘛 肯定是先乘后加

再看change操作

假如现在p有change标记以及multiply || add操作(我们已经搞清楚multiply和add操作了,就可以把他们看成一个操作ma就好了)

如果先change后ma 我们对lp、rp是不是就得先change后ma 相当于把 x1 x2都改成a 再乘4 相当于x1改成a乘4 x2改成a乘4

如果先ma后change 我们是不是ma的标记全被清空了 这样先change的话也没问题 因为对lp rp根本不会进行ma操作,因为标记都清空了

具体对于每个操作

change就是区间长度乘以对应的x的次数咯

multiply就是原来的和乘以对应的x的次数咯

add的话就要用到一点点初中还是高中知识

一次的话就没得说 原来的和加上区间长度乘以x

二次三次见下述公式

$\begin{aligned}\left( x_{1}+a\right) ^{2}+\left( x_{2}+a\right) ^{2}+\ldots +\left( x_{n}+a\right)^{2} = \left( x^{2}_{i}+x^{2}_{2}+\ldots +x^{2}_{n}\right) +2a\left( x_{1}+x_{2}+\ldots +x_{n}\right) +na^{2}\end{aligned}$

$\begin{aligned}\left( x_{1}+a\right) ^{3}+\left( x_{2}+a\right) ^{3}+\ldots +\left( x_{n}+a\right)^{3} = \left( x^{3}_{i}+x^{3}_{2}+\ldots +x^{3}_{n}\right) +3a^{2}\left( x_{1}+x_{2}+\ldots +x_{n}\right) + 3a\left( x^{2}_{1}+x^{2}_{2}+\ldots +x^{2}_{n}\right) +na^{2}\end{aligned}$

提取一下公因数

$\begin{aligned}\left( x_{1}+a\right) ^{3}+\left( x_{2}+a\right) ^{3}+\ldots +\left( x_{n}+a\right)^{3} = \left( x^{3}_{i}+x^{3}_{2}+\ldots +x^{3}_{n}\right) +3a\left( x^{2}_{1}+x^{2}_{2}+\ldots +x^{2}_{n}+ a\left(x_{1} + x_{2} + \ldots + x_{n}\right)\right) +na^{2}\end{aligned}$

因为求三次需要二次的和 求二次需要一次的和 那么就先算3次再算2次最后算1次

模运算部分因为太多项了。所以犯晕。保险的办法就是加括号后加一个%MOD 这样就比较保险

add和change清除后是0,multiply清楚后是1

代码如下

#include <cstdio>
#include <cstring>
#include <algorithm>
#define lp p<<1
#define rp p<<1|1
#define ll long long
#define MOD 10007
using namespace std;
const int maxn = 1e5 + ; ll add[maxn<<], multiply[maxn<<], change[maxn<<];
ll sum[maxn<<][];
inline void pushup(int p) {
for (int i = ; i <= ; i++) {
sum[p][i] = (sum[lp][i] + sum[rp][i]) % MOD;
}
}
void pushdown(int p, int llen, int rlen) {
if (change[p]) {
change[lp] = change[rp] = change[p];
multiply[lp] = multiply[rp] = ;
add[lp] = add[rp] = ;
sum[lp][] = (((((llen * change[p] % MOD) % MOD) * change[p] % MOD) % MOD) * change[p] % MOD) % MOD;
sum[rp][] = (((((rlen * change[p] % MOD) % MOD) * change[p] % MOD) % MOD) * change[p] % MOD) % MOD;
sum[lp][] = (((llen * change[p] % MOD) % MOD) * change[p] % MOD) % MOD;
sum[rp][] = (((rlen * change[p] % MOD) % MOD) * change[p] % MOD) % MOD;
sum[lp][] = (llen * change[p] % MOD) % MOD;
sum[rp][] = (rlen * change[p] % MOD) % MOD;
change[p] = ;
}
if (multiply[p] != ) {
if (add[lp]) add[lp] = add[lp] * multiply[p] % MOD;
if (add[rp]) add[rp] = add[rp] * multiply[p] % MOD;
multiply[lp] = multiply[lp] * multiply[p] % MOD;
multiply[rp] = multiply[rp] * multiply[p] % MOD;
sum[lp][] = ((((((sum[lp][] % MOD) * multiply[p] % MOD) % MOD) * multiply[p] % MOD) % MOD) * multiply[p] % MOD) % MOD;
sum[rp][] = ((((((sum[rp][] % MOD) * multiply[p] % MOD) % MOD) * multiply[p] % MOD) % MOD) * multiply[p] % MOD) % MOD;
sum[lp][] = ((((sum[lp][] % MOD) * multiply[p] % MOD) % MOD) * multiply[p] % MOD) % MOD;
sum[rp][] = ((((sum[rp][] % MOD) * multiply[p] % MOD) % MOD) * multiply[p] % MOD) % MOD;
sum[lp][] = ((sum[lp][] % MOD) * multiply[p] % MOD) % MOD;
sum[rp][] = ((sum[rp][] % MOD) * multiply[p] % MOD) % MOD;
multiply[p] = ;
}
if (add[p]) {
add[lp] = (add[lp] + add[p]) % MOD;
add[rp] = (add[rp] + add[p]) % MOD;
int temp = ((add[p] * add[p] % MOD) * add[p]) % MOD;
sum[lp][] = ((sum[lp][] + (temp * llen) % MOD) % MOD + (( * add[p] % MOD) * (sum[lp][] + sum[lp][] * add[p]) % MOD)) % MOD;
sum[rp][] = ((sum[rp][] + (temp * rlen) % MOD) % MOD + (( * add[p] % MOD) * (sum[rp][] + sum[rp][] * add[p]) % MOD)) % MOD;
sum[lp][] = (sum[lp][] + ((llen * add[p] % MOD) * add[p] % MOD) + (( * add[p] * sum[lp][]) % MOD)) % MOD;
sum[rp][] = (sum[rp][] + ((rlen * add[p] % MOD) * add[p] % MOD) + (( * add[p] * sum[rp][]) % MOD)) % MOD;
sum[lp][] = (sum[lp][] + ((llen * add[p]) % MOD)) % MOD;
sum[rp][] = (sum[rp][] + ((rlen * add[p]) % MOD)) % MOD;
add[p] = ;
}
}
void build(int p, int l, int r) {
multiply[p] = ;
add[p] = change[p] = ;
if (l == r) {
sum[p][] = sum[p][] = sum[p][] = ;
return;
}
int mid = l + r >> ;
build(lp, l, mid);
build(rp, mid + , r);
pushup(p);
}
void update(int p, int l, int r, int x, int y, int z, int type) {
if (x <= l && y >= r) {
if (type == ) {
add[p] += z; add[p] %= MOD;
sum[p][] = (sum[p][] + ((((((r - l + ) * z) % MOD) * z) % MOD) * z) % MOD + (( * z) % MOD) * (sum[p][] + (sum[p][] * z) % MOD)) % MOD;
sum[p][] = (sum[p][] + ((((r - l + ) * z) % MOD) * z) % MOD + ( * z * sum[p][] % MOD)) % MOD;
sum[p][] = (sum[p][] + ((r - l + ) * z) % MOD) % MOD;
} else if (type == ) {
multiply[p] = multiply[p] * z % MOD;
if (add[p]) add[p] = add[p] * z % MOD;
sum[p][] = (((((sum[p][] * z) % MOD) * z) % MOD) * z) % MOD;
sum[p][] = (((sum[p][] * z) % MOD) * z) % MOD;
sum[p][] = (sum[p][] * z) % MOD;
} else if (type == ) {
change[p] = z;
add[p] = ;
multiply[p] = ;
sum[p][] = ((((((r - l + ) * z) % MOD) * z) % MOD) * z) % MOD;
sum[p][] = ((((r - l + ) * z) % MOD) * z) % MOD;
sum[p][] = ((r - l + ) * z) % MOD;
}
return;
}
int mid = l + r >> ;
pushdown(p, mid - l + , r - mid);
if (x <= mid) update(lp, l, mid, x, y, z, type);
if (y > mid) update(rp, mid + , r, x, y, z, type);
pushup(p);
}
ll query(int p, int l, int r, int x, int y, int z) {
if (x <= l && y >= r) return sum[p][z] % MOD;
int mid = l + r >> ;
pushdown(p, mid - l + , r - mid);
ll res = ;
if (x <= mid) res = (res + query(lp, l, mid, x, y, z)) % MOD;
if (y > mid) res = (res + query(rp, mid + , r, x, y, z)) % MOD;
return res % MOD;
}
int main() {
int n, m;
while (~scanf("%d%d", &n, &m) && n || m) {
build(, , n);
int t, x, y, c;
while (m--) {
scanf("%d%d%d%d", &t, &x, &y, &c);
if (t == ) {
printf("%lld\n", query(, , n, x, y, c));
} else {
update(, , n, x, y, c, t);
}
}
}
return ;
}

hdu 4578 Transformation 线段树多种操作裸题的更多相关文章

  1. HDU 4578 Transformation --线段树,好题

    题意: 给一个序列,初始全为0,然后有4种操作: 1. 给区间[L,R]所有值+c 2.给区间[L,R]所有值乘c 3.设置区间[L,R]所有值为c 4.查询[L,R]的p次方和(1<=p< ...

  2. hdu 4578 Transformation 线段树

    没什么说的裸线段树,注意细节就好了!!! 代码如下: #include<iostream> #include<stdio.h> #include<algorithm> ...

  3. UESTC 1591 An easy problem A【线段树点更新裸题】

    An easy problem A Time Limit: 2000/1000MS (Java/Others)     Memory Limit: 65535/65535KB (Java/Others ...

  4. Transformation HDU - 4578(线段树——懒惰标记的妙用)

    Yuanfang is puzzled with the question below: There are n integers, a 1, a 2, …, a n. The initial val ...

  5. POJ 3667 线段树区间合并裸题

    题意:给一个n和m,表示n个房间,m次操作,操作类型有2种,一种把求连续未租出的房间数有d个的最小的最左边的房间号,另一个操作时把从x到x+d-1的房间号收回. 建立线段树,值为1表示未租出,0为租出 ...

  6. hdu 2871 线段树(各种操作)

    Memory Control Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) T ...

  7. hdu-3397 Sequence operation 线段树多种标记

    题目链接: http://acm.hdu.edu.cn/showproblem.php?pid=3397 题目大意: 0 a b表示a-b区间置为0 1 a b表示a-b区间置为1 2 a b表示a- ...

  8. 【线段树I:母题】hdu 1166 敌兵布阵

    [线段树I:母题]hdu 1166 敌兵布阵 题目链接:hdu 1166 敌兵布阵 题目大意 C国的死对头A国这段时间正在进行军事演习,所以C国间谍头子Derek和他手下Tidy又開始忙乎了.A国在海 ...

  9. hdu 4031 attack 线段树区间更新

    Attack Time Limit: 5000/3000 MS (Java/Others)    Memory Limit: 65768/65768 K (Java/Others)Total Subm ...

随机推荐

  1. keystone系列二:HTTP协议

    一 为何要学习HTTP协议 http协议就是通信的双方共同遵守的标准,就好比要合伙办事的两家公司签署的合同. openstack中各组件是基于restful api通信的,restful api可以单 ...

  2. FineUIMvc随笔(2)怎样在控件中嵌套 HTML

    声明:FineUIMvc(基础版)是免费软件,本系列文章适用于基础版. 用户需求 有网友在<FineUI总群1>问这么一个问题:怎么把 HTML 嵌套在控件中? 这是很多刚学习 FineU ...

  3. mysqldump 和mysqlbinlog

    一.mysqldump 1.备份test库 #mysqldump -uroot -p' test >test.sql 2.备份 -B参数 ' -B test >test_B.sql --B ...

  4. BZOJ4289 Tax 最短路建模

    给定一个带边权的无向图,求1到n的最小代价路径.经过一个点的代价是路径上这个点的入边和出边的较大权值. \(n \le 100000, m \le 200000\). 一般的建图是考虑每个点,其入边和 ...

  5. Linux登录MySQL时出现 Can't connect to local MySQL server through socket '/tmp/mysql.sock'解决方法

    在Linux上登录MySQL时出现如下提示,如下图: 通过查找资料了解到: MySQL有两种连接方式: (1)TCP/IP (2)socket 对mysql.sock来说,其作用是程序与mysqlse ...

  6. R语言

    什么是R语言编程? R语言是一种用于统计分析和为此目的创建图形的编程语言.不是数据类型,它具有用于计算的数据对象.它用于数据挖掘,回归分析,概率估计等领域,使用其中可用的许多软件包. R语言中的不同数 ...

  7. Echarts x轴文本内容太长的几种解决方案

    Echarts 标签中文本内容太长的时候怎么办 ? - 1对文本进行倾斜 在xAxis.axisLabe中修改rotate的值 xAxis: { data: ["衬衫11111", ...

  8. Windows之PowerShell使用命令

    Windows之PowerShell使用命令 切换 命令格式: cd [option] 切换到上一级目录 cd ../ 或者 cd .. 不同磁盘之间切换 盘符: 清屏 清空当前窗口的内容 cls 查 ...

  9. 福州大学软件工程1816 | W班 第8次作业[团队作业,随堂小测——校友录]

    作业链接 团队作业,随堂小测--校友录 评分细则 本次个人项目分数由两部分组成(博客分满分40分+程序得分满分60分) 博客和程序得分表 评分统计图 千帆竞发图 总结 旅法师:实现了更新,导出,查询, ...

  10. Python3练习题 011:成绩打分

    # print('-----判断输入值和60大小判断')# b=int(input('input num'))# if b >60:# print('良')# elif b==60:# prin ...