HDU - 4578 Transformation(线段树区间修改)
https://cn.vjudge.net/problem/HDU-4578
题意
4种操作,区间加,区间乘,区间变为一个数,求区间的和、平方和以及立方和。
分析
明显线段树,不过很麻烦。。看kuangbin大神的代码打的
用sum1,sum2,sum3分别代表和、平方和、立方和。
懒惰标记使用三个变量:
lazy1:是加的数
lazy2:是乘的倍数
lazy3:是赋值为一个常数,为0表示没有。
#include <stdio.h>
#include <string.h>
#include <iostream>
#include <algorithm>
#include <vector>
#include <queue>
#include <set>
#include <map>
#include <string>
#include <math.h>
#include <stdlib.h>
using namespace std;
const int MOD = ;
const int MAXN = ;
struct Node {
int l,r;
int sum1,sum2,sum3;
int lazy1,lazy2,lazy3;
} segTree[MAXN*];
void build(int i,int l,int r) {
segTree[i].l = l;
segTree[i].r = r;
segTree[i].sum1 = segTree[i].sum2 = segTree[i].sum3 = ;
segTree[i].lazy1 = segTree[i].lazy3 = ;
segTree[i].lazy2 = ;
int mid = (l+r)/;
if(l == r)return;
build(i<<,l,mid);
build((i<<)|,mid+,r);
}
void push_up(int i) {
if(segTree[i].l == segTree[i].r)
return;
segTree[i].sum1 = (segTree[i<<].sum1 + segTree[(i<<)|].sum1)%MOD;
segTree[i].sum2 = (segTree[i<<].sum2 + segTree[(i<<)|].sum2)%MOD;
segTree[i].sum3 = (segTree[i<<].sum3 + segTree[(i<<)|].sum3)%MOD; } void push_down(int i) {
if(segTree[i].l == segTree[i].r) return;
if(segTree[i].lazy3 != ) {
segTree[i<<].lazy3 = segTree[(i<<)|].lazy3 = segTree[i].lazy3;
segTree[i<<].lazy1 = segTree[(i<<)|].lazy1 = ;
segTree[i<<].lazy2 = segTree[(i<<)|].lazy2 = ;
segTree[i<<].sum1 = (segTree[i<<].r - segTree[i<<].l + )*segTree[i<<].lazy3%MOD;
segTree[i<<].sum2 = (segTree[i<<].r - segTree[i<<].l + )*segTree[i<<].lazy3%MOD*segTree[i<<].lazy3%MOD;
segTree[i<<].sum3 = (segTree[i<<].r - segTree[i<<].l + )*segTree[i<<].lazy3%MOD*segTree[i<<].lazy3%MOD*segTree[i<<].lazy3%MOD;
segTree[(i<<)|].sum1 = (segTree[(i<<)|].r - segTree[(i<<)|].l + )*segTree[(i<<)|].lazy3%MOD;
segTree[(i<<)|].sum2 = (segTree[(i<<)|].r - segTree[(i<<)|].l + )*segTree[(i<<)|].lazy3%MOD*segTree[(i<<)|].lazy3%MOD;
segTree[(i<<)|].sum3 = (segTree[(i<<)|].r - segTree[(i<<)|].l + )*segTree[(i<<)|].lazy3%MOD*segTree[(i<<)|].lazy3%MOD*segTree[(i<<)|].lazy3%MOD;
segTree[i].lazy3 = ;
}
if(segTree[i].lazy1 != || segTree[i].lazy2 != ) {
segTree[i<<].lazy1 = ( segTree[i].lazy2*segTree[i<<].lazy1%MOD + segTree[i].lazy1 )%MOD;
segTree[i<<].lazy2 = segTree[i<<].lazy2*segTree[i].lazy2%MOD;
int sum1,sum2,sum3;
sum1 = (segTree[i<<].sum1*segTree[i].lazy2%MOD + (segTree[i<<].r - segTree[i<<].l + )*segTree[i].lazy1%MOD)%MOD;
sum2 = (segTree[i].lazy2 * segTree[i].lazy2 % MOD * segTree[i<<].sum2 % MOD + *segTree[i].lazy1*segTree[i].lazy2%MOD * segTree[i<<].sum1%MOD + (segTree[i<<].r - segTree[i<<].l + )*segTree[i].lazy1%MOD*segTree[i].lazy1%MOD)%MOD;
sum3 = segTree[i].lazy2 * segTree[i].lazy2 % MOD * segTree[i].lazy2 % MOD * segTree[i<<].sum3 % MOD;
sum3 = (sum3 + *segTree[i].lazy2 % MOD * segTree[i].lazy2 % MOD * segTree[i].lazy1 % MOD * segTree[i<<].sum2) % MOD;
sum3 = (sum3 + *segTree[i].lazy2 % MOD * segTree[i].lazy1 % MOD * segTree[i].lazy1 % MOD * segTree[i<<].sum1) % MOD;
sum3 = (sum3 + (segTree[i<<].r - segTree[i<<].l + )*segTree[i].lazy1%MOD * segTree[i].lazy1 % MOD * segTree[i].lazy1 % MOD) % MOD;
segTree[i<<].sum1 = sum1;
segTree[i<<].sum2 = sum2;
segTree[i<<].sum3 = sum3;
segTree[i<<|].lazy1 = ( segTree[i].lazy2*segTree[i<<|].lazy1%MOD + segTree[i].lazy1 )%MOD;
segTree[i<<|].lazy2 = segTree[i<<|].lazy2*segTree[i].lazy2%MOD; sum1 = (segTree[i<<|].sum1*segTree[i].lazy2%MOD + (segTree[i<<|].r - segTree[i<<|].l + )*segTree[i].lazy1%MOD)%MOD;
sum2 = (segTree[i].lazy2 * segTree[i].lazy2 % MOD * segTree[i<<|].sum2 % MOD + *segTree[i].lazy1*segTree[i].lazy2%MOD * segTree[i<<|].sum1%MOD + (segTree[i<<|].r - segTree[i<<|].l + )*segTree[i].lazy1%MOD*segTree[i].lazy1%MOD)%MOD;
sum3 = segTree[i].lazy2 * segTree[i].lazy2 % MOD * segTree[i].lazy2 % MOD * segTree[i<<|].sum3 % MOD;
sum3 = (sum3 + *segTree[i].lazy2 % MOD * segTree[i].lazy2 % MOD * segTree[i].lazy1 % MOD * segTree[i<<|].sum2) % MOD;
sum3 = (sum3 + *segTree[i].lazy2 % MOD * segTree[i].lazy1 % MOD * segTree[i].lazy1 % MOD * segTree[i<<|].sum1) % MOD;
sum3 = (sum3 + (segTree[i<<|].r - segTree[i<<|].l + )*segTree[i].lazy1%MOD * segTree[i].lazy1 % MOD * segTree[i].lazy1 % MOD) % MOD;
segTree[i<<|].sum1 = sum1;
segTree[i<<|].sum2 = sum2;
segTree[i<<|].sum3 = sum3;
segTree[i].lazy1 = ;
segTree[i].lazy2 = ; }
}
void update(int i,int l,int r,int type,int c) {
if(segTree[i].l >= l && segTree[i].r <= r) {
c %= MOD;
if(type == ) {
segTree[i].lazy1 += c;
segTree[i].lazy1 %= MOD;
segTree[i].sum3 = (segTree[i].sum3 + *segTree[i].sum2%MOD*c%MOD + *segTree[i].sum1%MOD*c%MOD*c%MOD + (segTree[i].r - segTree[i].l + )*c%MOD*c%MOD*c%MOD)%MOD;
segTree[i].sum2 = (segTree[i].sum2 + *segTree[i].sum1%MOD*c%MOD + (segTree[i].r - segTree[i].l + )*c%MOD*c%MOD)%MOD;
segTree[i].sum1 = (segTree[i].sum1 + (segTree[i].r - segTree[i].l + )*c%MOD)%MOD;
} else if(type == ) {
segTree[i].lazy1 = segTree[i].lazy1*c%MOD;
segTree[i].lazy2 = segTree[i].lazy2*c%MOD;
segTree[i].sum1 = segTree[i].sum1*c%MOD;
segTree[i].sum2 = segTree[i].sum2*c%MOD*c%MOD;
segTree[i].sum3 = segTree[i].sum3*c%MOD*c%MOD*c%MOD;
} else {
segTree[i].lazy1 = ;
segTree[i].lazy2 = ;
segTree[i].lazy3 = c%MOD;
segTree[i].sum1 = c*(segTree[i].r - segTree[i].l + )%MOD;
segTree[i].sum2 = c*(segTree[i].r - segTree[i].l + )%MOD*c%MOD;
segTree[i].sum3 = c*(segTree[i].r - segTree[i].l + )%MOD*c%MOD*c%MOD;
}
return;
}
push_down(i);
int mid = (segTree[i].l + segTree[i].r)/;
if(l <= mid)update(i<<,l,r,type,c);
if(r > mid)update((i<<)|,l,r,type,c);
push_up(i);
}
int query(int i,int l,int r,int p) {
if(segTree[i].l >= l && segTree[i].r <= r) {
if(p == )return segTree[i].sum1;
else if(p== )return segTree[i].sum2;
else return segTree[i].sum3;
}
push_down(i);
int mid = (segTree[i].l + segTree[i].r )/;
int sum=;
if(l <= mid) sum+=query(i<<,l,r,p);
if(r > mid) sum+=query((i<<)|,l,r,p);
return sum%MOD;
} int main() {
//freopen("in.txt","r",stdin);
//freopen("out.txt","w",stdout);
int n,m;
while(scanf("%d%d",&n,&m) == ) {
if(n == && m == )break;
build(,,n);
int type,x,y,c;
while(m--) {
scanf("%d%d%d%d",&type,&x,&y,&c);
if(type == )printf("%d\n",query(,x,y,c));
else update(,x,y,type,c);
}
}
return ;
}
HDU - 4578 Transformation(线段树区间修改)的更多相关文章
- HDU 4578 Transformation --线段树,好题
题意: 给一个序列,初始全为0,然后有4种操作: 1. 给区间[L,R]所有值+c 2.给区间[L,R]所有值乘c 3.设置区间[L,R]所有值为c 4.查询[L,R]的p次方和(1<=p< ...
- hdu 4578 Transformation 线段树多种操作裸题
自己写了一个带结构体的WA了7.8次 但是测了几组小数据都对..感觉问题应该出在模运算那里.写完这波题解去对拍一下. 以后线段树绝不写struct!一般的struct都带上l,r 但是一条线段的长度确 ...
- hdu 4578 Transformation 线段树
没什么说的裸线段树,注意细节就好了!!! 代码如下: #include<iostream> #include<stdio.h> #include<algorithm> ...
- 题解报告:hdu 1698 Just a Hook(线段树区间修改+lazy懒标记的运用)
Problem Description In the game of DotA, Pudge’s meat hook is actually the most horrible thing for m ...
- hdu 4031 attack 线段树区间更新
Attack Time Limit: 5000/3000 MS (Java/Others) Memory Limit: 65768/65768 K (Java/Others)Total Subm ...
- Codeforces Round #442 (Div. 2) E Danil and a Part-time Job (dfs序加上一个线段树区间修改查询)
题意: 给出一个具有N个点的树,现在给出两种操作: 1.get x,表示询问以x作为根的子树中,1的个数. 2.pow x,表示将以x作为根的子树全部翻转(0变1,1变0). 思路:dfs序加上一个线 ...
- poj 2528 线段树区间修改+离散化
Mayor's posters POJ 2528 传送门 线段树区间修改加离散化 #include <cstdio> #include <iostream> #include ...
- E - Just a Hook HDU - 1698 线段树区间修改区间和模版题
题意 给出一段初始化全为1的区间 后面可以一段一段更改成 1 或 2 或3 问最后整段区间的和是多少 思路:标准线段树区间和模版题 #include<cstdio> #include& ...
- HDU 4027 Can you answer these queries? (线段树区间修改查询)
描述 A lot of battleships of evil are arranged in a line before the battle. Our commander decides to u ...
- HDU 3308 (线段树区间合并)
http://acm.hdu.edu.cn/showproblem.php?pid=3308 题意: 两个操作 : 1 修改 单点 a 处的值. 2 求出 区间[a,b]内的最长上升子序列. 做法 ...
随机推荐
- GCD HDU - 2588
输入 N 和 M (2<=N<=1000000000, 1<=M<=N), 找出所有满足1<=X<=N 且 gcd(X,N)>=M 的 X 的数量. Inpu ...
- 「AtCoder Grand018A」Getting Difference(GCD)
题目链接A - Getting Difference 题意 有n(1~\(10^5\))个数\(A_i\) (1~\(10^9\)),每次选两个数,将它们的差的绝对值加入这堆数.问k(1~\(10^9 ...
- Python将是人工智能时代的最佳编程语言
Python将是人工智能时代的最佳编程语言 移动互联网取代PC互联网领跑在互联网时代的最前沿,Android和iOS一度成为移动互联网应用平台的两大霸主,成为移动开发者首选的两门技术,HTML5以其跨 ...
- Nifi 模板
Acqusition_and_Processing.xml Moving templates to own directory to make repo cleaner CADF_Pars ...
- HDU 2604 Queuing(矩阵快速幂)
题目链接:Queuing 题意:有一支$2^L$长度的队伍,队伍中有female和male,求$2^L$长度的队伍中除 fmf 和 fff 的队列有多少. 题解:先推导递推式:$f[i]=f[i-1] ...
- poj2524(并查集水题)
题目链接:http://poj.org/problem?id=2524 题目大意:学校共有n个同学,告诉你m对同学信仰同一宗教,问这个学校学生信仰宗教的数目最多为多少. 例: Sample Input ...
- 2.Linux基础命令
linux内一切皆文件,没有文件夹只有目录,目录也是一种文件 1.一些常用按键: 将鼠标的光标从虚拟机里切换回来:Ctrl+Alt 拖动Ubuntu内的对话框:Alt键+鼠标左键拖动 清屏:Ctrl+ ...
- bcftools或vcftools提取指定区段的vcf文件(extract specified position )
下载安装bcftools 见如下命令: bcftools filter 1000Genomes.vcf.gz --regions 9:4700000-4800000 > 4700000-4800 ...
- 从 date 中取出 小时和分钟进行比较
public class T1 { public static void main(String[] args) throws ParseException { SimpleDateFormat df ...
- Xml二(解析思想)、
XML解析: * 解析xml可以做: * 如果xml作为配置文件:读取 * 如果xml作为传输文件:写,读 * xml解析思想: * DOM:将文档加载进内存,形成一颗dom树(document对象) ...