HDU 4578 Transformation (线段树)
Transformation
Time Limit: 15000/8000 MS (Java/Others) Memory Limit: 65535/65536 K (Java/Others)
Total Submission(s): 49 Accepted Submission(s): 16
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.
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.
3 3 5 7
1 2 4 4
4 1 5 2
2 2 5 8
4 3 5 3
0 0
7489
很裸的线段树的题目。
但是做起来比较麻烦。
我用sum1,sum2,sum3分别代表和、平方和、立方和。
懒惰标记使用三个变量:
lazy1:是加的数
lazy2:是乘的倍数
lazy3:是赋值为一个常数,为0表示没有。
更新操作需要注意很多细节。
/* **********************************************
Author : kuangbin
Created Time: 2013/8/10 13:24:03
File Name : F:\2013ACM练习\比赛练习\2013杭州邀请赛重现\1003.cpp
*********************************************** */ #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(r <= mid)update(i<<,l,r,type,c);
else if(l > mid)update((i<<)|,l,r,type,c);
else
{
update(i<<,l,mid,type,c);
update((i<<)|,mid+,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 )/;
if(r <= mid)return query(i<<,l,r,p);
else if(l > mid)return query((i<<)|,l,r,p);
else return (query(i<<,l,mid,p)+query((i<<)|,mid+,r,p))%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 线段树
没什么说的裸线段树,注意细节就好了!!! 代码如下: #include<iostream> #include<stdio.h> #include<algorithm> ...
- hdu 4578 Transformation 线段树多种操作裸题
自己写了一个带结构体的WA了7.8次 但是测了几组小数据都对..感觉问题应该出在模运算那里.写完这波题解去对拍一下. 以后线段树绝不写struct!一般的struct都带上l,r 但是一条线段的长度确 ...
- Transformation HDU - 4578(线段树——懒惰标记的妙用)
Yuanfang is puzzled with the question below: There are n integers, a 1, a 2, …, a n. The initial val ...
- hdu 4031 attack 线段树区间更新
Attack Time Limit: 5000/3000 MS (Java/Others) Memory Limit: 65768/65768 K (Java/Others)Total Subm ...
- hdu 4288 离线线段树+间隔求和
Coder Time Limit: 20000/10000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others) Total Su ...
- hdu 3016 dp+线段树
Man Down Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others) Total S ...
- HDU 4578 - Transformation - [加强版线段树]
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=4578 Problem Description Yuanfang is puzzled with the ...
- HDU 4578——Transformation——————【线段树区间操作、确定操作顺序】
Transformation Time Limit: 15000/8000 MS (Java/Others) Memory Limit: 65535/65536 K (Java/Others)T ...
随机推荐
- Linux 入门记录:七、fdisk 分区工具
一.fdisk分区工具 fdisk 是来自 IBM 的老牌分区工具,支持绝大多数操作系统,几乎所有的 Linux 发行版都装有 fdisk,包括在 Linux 的 resuce 模式下依然能够使用. ...
- mongodb 学习笔记 2 --- 修改器
修改器是为了爱update文档时,不需要传入整个文档就能修改当前文档的某个属性值,修改器用法如下: 假设数据库中foo集合中存在如下文档:{"name":"jack&qu ...
- 设计模式之笔记--组合模式(Composite)
组合模式(Composite) 定义 组合模式(Composite),将对象组合成树形结构以表示“部分-整体”的层次结构.组合模式使得用户对单个对象和组合对象的使用具有一致性. 组合模式有 ...
- aspxgridview export导出数据,把true显示成‘是’
项目原因,数据库中的数据是‘true’还有‘false’,但是在页面上要显示为‘是否’,导出来的时候也是要显示成‘是否’ 要在web页面当中显示成‘是否’,只要在gridview的CustomColu ...
- C#ActiveX安装项目
C#开发的ActiveX控件发布方式有三种: 制作客户端安装包,分发给客户机安装: 制作在线安装包,客户机联机安装: 使用html中object的codebase指向安装包地址. 以下为制作安装包: ...
- 0,null,undefined,[],{},'',false之间的关系
0与一些虚值的比较: 0与false 0==false true 0与'': =='' true 0与[]: ==[] true 0与NaN: 0==NaN false 0与undefined 0== ...
- Spring学习(二)——Spring中的AOP的初步理解
[前面的话] Spring对我太重要了,做个关于web相关的项目都要使用Spring,每次去看Spring相关的知识,总是感觉一知半解,没有很好的系统去学习一下,现在抽点时间学习一下Spring.不知 ...
- 使用css让文字两端对齐
text-align:justify; text-justify:distribute-all-lines; text-align-last:justify;可以让文字实现两端对齐
- HDU 5669 Road(线段树建树)(分层图最短路)
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=5669 [分析]线段树建树+分层图最短路 #include <cstdio> #includ ...
- Linux命令之find(二)
接上一篇Linux命令之find(一) (1).实例 1.列出当前目录下及子目录下所有的.txt文件 [xf@xuexi ~]$ ls 1.txt 3.txt b.txt 公共 视频 文档 音乐 2. ...