HDU 4578——Transformation——————【线段树区间操作、确定操作顺序】
Transformation
Time Limit: 15000/8000 MS (Java/Others) Memory Limit: 65535/65536 K (Java/Others)
Total Submission(s): 3830 Accepted Submission(s): 940
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.
- #include<bits/stdc++.h>
- using namespace std;
- #define mid (L+R)/2
- #define lson rt*2,L,mid
- #define rson rt*2+1,mid+1,R
- typedef long long INT;
- const int maxn = 120000;
- const int mod = 10007;
- struct SegTree{
- int add,multi,setv;
- int sum1,sum2,sum3;
- }segs[maxn*4];
- void PushUp(int rt,int L,int R){
- segs[rt].sum1 = (segs[rt*2].sum1 + segs[rt*2+1].sum1)% mod;
- segs[rt].sum2 = (segs[rt*2].sum2 + segs[rt*2+1].sum2)% mod;
- segs[rt].sum3 = (segs[rt*2].sum3 + segs[rt*2+1].sum3)% mod;
- }
- void buildtree(int rt,int L,int R){
- segs[rt].multi = 1;
- segs[rt].add = segs[rt].setv = 0;
- segs[rt].sum1 = segs[rt].sum2 = segs[rt].sum3 = 0;
- if(L == R){
- return ;
- }
- buildtree(lson);
- buildtree(rson);
- }
- void PushDown(int rt,int L,int R){
- if(segs[rt].setv){ //考虑下放赋值标记
- segs[rt*2].setv = segs[rt*2+1].setv = segs[rt].setv;
- segs[rt*2].add = segs[rt*2+1].add = 0;
- segs[rt*2].multi = segs[rt*2+1].multi = 1;
- segs[rt*2].sum1 = (mid-L+1)*segs[rt].setv % mod;
- segs[rt*2].sum2 = (mid-L+1)*segs[rt].setv %mod *segs[rt].setv % mod;
- segs[rt*2].sum3 = (mid-L+1)*segs[rt].setv %mod *segs[rt].setv % mod *segs[rt].setv % mod;
- segs[rt*2+1].sum1 = (R-mid)*segs[rt].setv % mod;
- segs[rt*2+1].sum2 = (R-mid)*segs[rt].setv % mod *segs[rt].setv % mod;
- segs[rt*2+1].sum3 = (R-mid)*segs[rt].setv % mod *segs[rt].setv % mod *segs[rt].setv % mod;
- segs[rt].setv = 0;
- }
- if(segs[rt].multi != 1 || segs[rt].add){//如果有加和标记或者乘积标记
- segs[rt*2].add = (segs[rt].multi * segs[rt*2].add %mod + segs[rt].add) % mod;
- segs[rt*2].multi = segs[rt].multi * segs[rt*2].multi % mod;
- int sum1, sum2 ,sum3;
- //一次方和
- sum1 = (segs[rt*2].sum1*segs[rt].multi %mod + (mid-L+1)*segs[rt].add %mod) % mod;
- //平方和
- sum2 = (segs[rt*2].sum2*segs[rt].multi %mod *segs[rt].multi %mod + 2*segs[rt].add * segs[rt].multi %mod *segs[rt*2].sum1 %mod + (mid-L+1)*segs[rt].add %mod *segs[rt].add %mod ) % mod;
- //三次方和
- sum3 = segs[rt*2].sum3*segs[rt].multi %mod *segs[rt].multi %mod *segs[rt].multi %mod;
- sum3 = (sum3 + 3*segs[rt].add*segs[rt].multi %mod *segs[rt].multi %mod *segs[rt*2].sum2 %mod) % mod;
- sum3 = (sum3 + 3*segs[rt].add*segs[rt].add %mod *segs[rt].multi %mod *segs[rt*2].sum1 %mod ) % mod;
- sum3 = (sum3 + (mid-L+1)*segs[rt].add %mod *segs[rt].add %mod *segs[rt].add %mod ) % mod;
- segs[rt*2].sum1 = sum1;
- segs[rt*2].sum2 = sum2;
- segs[rt*2].sum3 = sum3;
- //同理,更新右儿子
- segs[rt*2+1].add = (segs[rt*2+1].add*segs[rt].multi %mod + segs[rt].add) % mod;
- segs[rt*2+1].multi = segs[rt*2+1].multi * segs[rt].multi % mod;
- sum1 = (segs[rt*2+1].sum1*segs[rt].multi %mod + (R-mid)*segs[rt].add %mod) % mod;
- sum2 = (segs[rt*2+1].sum2*segs[rt].multi %mod *segs[rt].multi %mod + 2*segs[rt].add*segs[rt].multi %mod *segs[rt*2+1].sum1 %mod + (R-mid)*segs[rt].add %mod *segs[rt].add %mod) % mod;
- sum3 = segs[rt*2+1].sum3*segs[rt].multi %mod *segs[rt].multi %mod *segs[rt].multi %mod;
- sum3 = (sum3 + 3*segs[rt].add*segs[rt].multi %mod *segs[rt].multi %mod *segs[rt*2+1].sum2 %mod) % mod;
- sum3 = (sum3 + 3*segs[rt].add*segs[rt].add %mod *segs[rt].multi %mod *segs[rt*2+1].sum1 %mod ) % mod;
- sum3 = (sum3 + (R-mid)*segs[rt].add %mod *segs[rt].add %mod *segs[rt].add %mod ) % mod;
- segs[rt*2+1].sum1 = sum1;
- segs[rt*2+1].sum2 = sum2;
- segs[rt*2+1].sum3 = sum3;
- segs[rt].add = 0;
- segs[rt].multi = 1;
- }
- }
- void Update(int rt,int L,int R,int l_ran,int r_ran,int c,int typ){
- if(l_ran <= L&&R <= r_ran){
- if(typ == 1){ //加和
- segs[rt].add = (segs[rt].add + c)%mod;
- segs[rt].sum3 = (segs[rt].sum3 + (R-L+1)*c %mod *c %mod *c %mod + 3*c %mod *segs[rt].sum2 %mod + 3*c %mod *c %mod *segs[rt].sum1 %mod ) % mod;
- segs[rt].sum2 = (segs[rt].sum2 + (R-L+1)*c %mod *c %mod + 2*segs[rt].sum1 %mod *c %mod ) % mod;
- segs[rt].sum1 = ((R-L+1)*c %mod + segs[rt].sum1) % mod;
- }else if(typ == 2){ //乘积
- //乘积对当前节点的和跟乘都有影响
- segs[rt].add = segs[rt].add * c % mod;
- segs[rt].multi = segs[rt].multi * c % mod;
- segs[rt].sum1 = segs[rt].sum1 * c % mod;
- segs[rt].sum2 = segs[rt].sum2 * c %mod *c %mod;
- segs[rt].sum3 = segs[rt].sum3 *c %mod *c %mod *c % mod;
- }else{ //赋值
- segs[rt].setv = c;
- segs[rt].multi = 1;
- segs[rt].add = 0;
- segs[rt].sum1 = c*(R-L+1) % mod;
- segs[rt].sum2 = c*(R-L+1) % mod*c % mod;
- segs[rt].sum3 = c*(R-L+1) % mod*c % mod *c %mod ;
- }
- return ;
- }
- PushDown(rt,L,R);
- if(l_ran <= mid)
- Update(lson,l_ran,r_ran,c,typ);
- if(r_ran > mid)
- Update(rson,l_ran,r_ran,c,typ);
- PushUp(rt,L,R);
- }
- int query(int rt,int L,int R,int l_ran,int r_ran,int pw){
- if(l_ran <= L&&R <= r_ran){
- if(pw == 1){
- return segs[rt].sum1;
- }else if(pw == 2){
- return segs[rt].sum2;
- }else{
- return segs[rt].sum3;
- }
- }
- PushDown(rt,L,R);
- int ret = 0;
- if(l_ran <= mid){
- ret = (ret + query(lson,l_ran,r_ran,pw)) % mod;
- }
- if(r_ran > mid){
- ret = (ret + query(rson,l_ran,r_ran,pw)) % mod;
- }
- return ret;
- }
- int main(){
- int n,m;
- while(scanf("%d%d",&n,&m)!=EOF&&(n+m)){
- int c,u,v,w;
- buildtree(1,1,n);
- for(int i = 1; i <= m; i++){
- scanf("%d%d%d%d",&c,&u,&v,&w);
- if(c == 4){
- int res = query(1,1,n,u,v,w);
- printf("%d\n",res);
- }else {
- Update(1,1,n,u,v,w,c);
- }
- }
- }
- return 0;
- }
HDU 4578——Transformation——————【线段树区间操作、确定操作顺序】的更多相关文章
- hdu 4578 Transformation 线段树多种操作裸题
自己写了一个带结构体的WA了7.8次 但是测了几组小数据都对..感觉问题应该出在模运算那里.写完这波题解去对拍一下. 以后线段树绝不写struct!一般的struct都带上l,r 但是一条线段的长度确 ...
- 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 4031 attack 线段树区间更新
Attack Time Limit: 5000/3000 MS (Java/Others) Memory Limit: 65768/65768 K (Java/Others)Total Subm ...
- HDU 3308 (线段树区间合并)
http://acm.hdu.edu.cn/showproblem.php?pid=3308 题意: 两个操作 : 1 修改 单点 a 处的值. 2 求出 区间[a,b]内的最长上升子序列. 做法 ...
- HDU 3308 LCIS (线段树区间合并)
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=3308 题目很好懂,就是单点更新,然后求区间的最长上升子序列. 线段树区间合并问题,注意合并的条件是a[ ...
- hdu 5023(线段树区间染色,统计区间内颜色个数)
题目描述:区间染色问题,统计给定区间内有多少种颜色? 线段树模板的核心是对标记的处理 可以记下沿途经过的标记,到达目的节点之后一块算,也可以更新的时候直接更新到每一个节点 Lazy操作减少修改的次数( ...
- Bzoj 1798: [Ahoi2009]Seq 维护序列seq(线段树区间操作)
1798: [Ahoi2009]Seq 维护序列seq Time Limit: 30 Sec Memory Limit: 64 MB Description 老师交给小可可一个维护数列的任务,现在小可 ...
- LCIS HDU - 3308 (线段树区间合并)
LCIS HDU - 3308 Given n integers. You have two operations: U A B: replace the Ath number by B. (inde ...
- POJ 2528 ——Mayor's posters(线段树+区间操作)
Time limit 1000 ms Memory limit 65536 kB Description The citizens of Bytetown, AB, could not stand t ...
随机推荐
- windows下部署icescrum
软件151 卢炜杰 一.安装JDK 1.下载JDK 地址:http://www.oracle.com/technetwork/java/javaee/downloads/index.html 选择相 ...
- Ground Truth
ground truth就是参考标准,一般用来做误差量化.比方说要根据历史数据预测某一时间的温度,ground truth就是那个时间的真实温度.error就是(predicted temperatu ...
- Python3中开发目录的引用
Python3中开发目录的引用 import os,sys BASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__))) ...
- loj #2026. 「JLOI / SHOI2016」成绩比较
#2026. 「JLOI / SHOI2016」成绩比较 题目描述 THU 的 G 系中有许许多多的大牛,比如小 R 的室友 B 神.B 神已经厌倦了与其他的同学比较 GPA(Grade Poin ...
- apache2.4.X虚拟主机配置
1,用记事本打开apache目录下httpd文件(如:D:\wamp\bin\apache\apache2.2.8\conf),找到如下模块 # Virtual hosts #In ...
- 阿里云linux安装jmeter并进行压测
一.阿里云linux安装JDK 1.下载安装JDK jdk官网,选择linux版本,下载并保存. (一)yum安装 安装epel的yumyuan yum install epel-release -y ...
- Linux安装vim编辑器
1.ubuntu系统:普通用户下输入命令:sudo apt-get install vim-gtk (注:出现E: Unable to locate package则将命令改成sudo apt-get ...
- Laplace(拉普拉斯)算子
[摘要] Laplace算子作为边缘检测之一,和Sobel算子一样也是工程数学中常用的一种积分变换,属于空间锐化滤波操作.拉普拉斯算子(Laplace Operator)是n维欧几里德空间中的一个二阶 ...
- Express全系列教程之(十):jade模板引擎
一.前言 随着前端业务的不断发展,页面交互逻辑的不断提高,让数据和界面实现分离渐渐被提了出来.JavaScript的MVC思想也流行了起来,在这种背景下,基于node.js的模板引擎也随之出现. 什么 ...
- hdu6441 Find Integer 求勾股数 费马大定理
题目传送门 题目大意: 给出a和n,求满足的b和c. 思路: 数论题目,没什么好说的. 根据费马大定理,当n>2时不存在正整数解. 当n=0或者1时特判一下就可以了,也就是此时变成了一个求勾股数 ...