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 ...
随机推荐
- c语言简单实现telnet客户端
c语言简单实现telnet客户端 http://blog.csdn.net/haiwenchen/article/details/69944118
- 快速排序算法的c++实现
很早以前看过快排算法觉得自己掌握了,,课今天用的时候发现老出错,认真想想发现自己一直搞错了... 下面先说一下我的想法: 首先,快排的思想就是 从数列中挑出一个元素,称为 "基准" ...
- [New learn]讲解Objective-c的block知识-实践
1.简介 在之前的文章[New learn]讲解Objective-c的block知识中介绍了block的相关知识.本章中我们将以一个实际例子来简单介绍一下block如何代替代理. 2.原有通过代理实 ...
- c语言实现CRC校验和
最近在摄像头采集的数据清晰度上需要加强,则在每一帧传输的数据包后边加了CRC校验和.CRC校验和有16位的,也有32位的.至于CRC校验和算法原理,我是在百度上学习的,其实网上有很多这种资料.简单的说 ...
- [PAT] 1021 Deepest Root (25)(25 分)
1021 Deepest Root (25)(25 分)A graph which is connected and acyclic can be considered a tree. The hei ...
- Python 邮件发送消息
# 代码 #!/usr/bin/env python # -*- coding:utf-8 -*- # Author:supery import smtplib from email.mime.tex ...
- python类的使用与多文件组织
多文件的组织 跨目录级导入模块 from ..xxfile import xxmodule #从上级目录中的xxfile中导入xxmodule import xxsub_dir.xxfile #从xx ...
- 洛谷P3038 牧草种植 [树链剖分]
题目传送门 牧草种植 题目描述 Farmer John has N barren pastures (2 <= N <= 100,000) connected by N-1 bidirec ...
- 主元素 II
主元素 II 给定一个整型数组,找到主元素,它在数组中的出现次数严格大于数组元素个数的三分之一. 样例 给出数组[1,2,1,2,1,3,3] 返回 1 注意 数组中只有唯一的主元素 挑战 要求时间复 ...
- Eclipse有助于提高开发速度的快捷键
用Eclipse已经很长一段时间了,自己常用的几个快捷键也已经很熟,但还是有一些自己不经常在开发中使用,但非常使用的快捷键,记录下来,以后利用来提高开发效率. 1.ctrl + shift + r ...