线段树上的多操作。。。

题目大意:

树上 的初始值为0,然后有下列三种操作和求和。

1  x y c  在X-Y的之间全部加上C。

2  x y c  在X-Y的之间全部乘上C。

3  x y c  在X-Y之间的全部变成C。

4  x y c  输出在X-Y之间的所有数的C方的和。。。

思路:

因为存在两种不兼容的操作(如果直接放一起的话会出现顺序不同的影响,(3+2)*4   和 3*4+2  显然是不一样的)

所以每次合并操作的时候  就要把子树的操作推下去清除掉。

当然  如果这个区间的所有值都是一样的话。那么可以直接进行操作。

然后就是Query了。

因为要求出很多的平方 或者 立方和。

那么我们就去找所有区间的值是一样的区间。拿出来现乘方  再算有多少个。

#include <iostream>
#include <cstdio>
#include <algorithm>
#include <cmath>
#include <cstring>
#define lson num<<1,s,mid
#define rson num<<1|1,mid+1,e
#define maxn 100005
const int mod = 10007;
using namespace std; int add[maxn<<2];
int mul[maxn<<2];
int cov[maxn<<2];
int tre[maxn<<2];
int n,m; void pushdown(int num)
{
if(cov[num])//如果这个区间是值一样的
{
tre[num<<1]=tre[num<<1|1]=tre[num];
cov[num<<1]=cov[num<<1|1]=1;
add[num<<1]=add[num<<1|1]=0;
mul[num<<1]=mul[num<<1|1]=1;
cov[num]=0;
return;
}
if(add[num]!=0)//不一样的话 要把ADD推下去
{
if(cov[num<<1])
{
tre[num<<1]+=add[num];
tre[num<<1]%=mod;
}
else
{
pushdown(num<<1);
add[num<<1]+=add[num];
add[num<<1]%=mod;
} if(cov[num<<1|1])
{
tre[num<<1|1]+=add[num];
tre[num<<1|1]%=mod;
}
else
{
pushdown(num<<1|1);
add[num<<1|1]+=add[num];
add[num<<1|1]%=mod;
} add[num]=0;
}
if(mul[num]!=1)
{
if(cov[num<<1])
{
tre[num<<1]*=mul[num];
tre[num<<1]%=mod;
}
else
{
mul[num<<1]*=mul[num];
mul[num<<1]%=mod;
} if(cov[num<<1|1])
{
tre[num<<1|1]*=mul[num];
tre[num<<1|1]%=mod;
}
else
{
mul[num<<1|1]*=mul[num];
mul[num<<1|1]%=mod;
}
mul[num]=1;
}
} void build(int num,int s,int e)
{
add[num]=0;
mul[num]=1;
cov[num]=0;
tre[num]=0;
if(s==e)
{
cov[num]=1;
return;
}
int mid=(s+e)>>1;
build(lson);
build(rson);
} void update(int num,int s,int e,int l,int r,int val,int op)
{
if(l<=s && r>=e)
{
if(op==3)
{
add[num]=0;
mul[num]=1;
cov[num]=1;
tre[num]=val;
}
else
{
if(cov[num])
{
if(op==1)
{
tre[num]+=val;
tre[num]%=mod;
}
else
{
tre[num]*=val;
tre[num]%=mod;
}
}
else
{
pushdown(num); if(op==1)
{
add[num]+=val;
add[num]%=mod;
}
else
{
mul[num]*=val;
mul[num]%=mod;
}
}
}
return;
} pushdown(num); int mid=(s+e)>>1; if(l<=mid)update(lson,l,r,val,op);
if(r>mid)update(rson,l,r,val,op);
} int Q_Q(int num,int s,int e,int c)
{
printf("```%d\n",num);
int mid=(s+e)>>1;
if(cov[num]==1)
{
int tmp=1;
for(int aa=0;aa<c;aa++)
{
tmp*=tre[num];
tmp%=mod;
}
tmp*=(e-s+1);
tmp%=mod;
return tmp;
}
pushdown(num);
Q_Q(lson,c);
Q_Q(rson,c);
}
int query(int num,int s,int e,int l,int r,int c)
{
int mid=(s+e)>>1;
if(l==s && r==e)
{
if(cov[num])
{
int tmp=1;
while(c--)
{
tmp*=tre[num];
tmp%=mod;
}
tmp*=(e-s+1);
tmp%=mod;
return tmp;
}
}
pushdown(num); if(r<=mid)return query(lson,l,r,c);
else if(l>mid)return query(rson,l,r,c);
else return (query(lson,l,mid,c) + query(rson,mid+1,r,c))%mod;
}
int main()
{
while(scanf("%d%d",&n,&m)!=EOF)
{
if(n==0 && m==0)break;
int op,lef,rig,c;
build(1,1,n);
while(m--)
{
scanf("%d%d%d%d",&op,&lef,&rig,&c); if(op!=4)update(1,1,n,lef,rig,c,op);
else printf("%d\n",query(1,1,n,lef,rig,c)%mod);
}
}
return 0;
}

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. hdu 4578 Transformation 线段树多种操作裸题

    自己写了一个带结构体的WA了7.8次 但是测了几组小数据都对..感觉问题应该出在模运算那里.写完这波题解去对拍一下. 以后线段树绝不写struct!一般的struct都带上l,r 但是一条线段的长度确 ...

  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. hdu 4031 attack 线段树区间更新

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

  6. hdu 4288 离线线段树+间隔求和

    Coder Time Limit: 20000/10000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) Total Su ...

  7. hdu 3016 dp+线段树

    Man Down Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) Total S ...

  8. HDU 4578 - Transformation - [加强版线段树]

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=4578 Problem Description Yuanfang is puzzled with the ...

  9. HDU 4578 Transformation (线段树)

    Transformation Time Limit: 15000/8000 MS (Java/Others)    Memory Limit: 65535/65536 K (Java/Others)T ...

  10. HDU 4578——Transformation——————【线段树区间操作、确定操作顺序】

    Transformation Time Limit: 15000/8000 MS (Java/Others)    Memory Limit: 65535/65536 K (Java/Others)T ...

随机推荐

  1. POJ 1166 The Clocks (爆搜 || 高斯消元)

    题目链接 题意: 输入提供9个钟表的位置(钟表的位置只能是0点.3点.6点.9点,分别用0.1.2.3)表示.而题目又提供了9的步骤表示可以用来调正钟的位置,例如1 ABDE表示此步可以在第一.二.四 ...

  2. multipath 安装配置

    二. 安装配置 2.1 安装Multipath 查看相关包: [root@rac1 ~]# rpm -qa|grep device-mapper device-mapper-multipath-0.4 ...

  3. cocos2d-x 滚动文字(二)

    http://blog.csdn.net/kuovane/article/details/8131789 首先送上demo,下载地址为:demo下载地址 一,怎么在文字前面空两隔?只需在xml里的文字 ...

  4. Android SharedPreferences 权限设置

    说明: 由于目前打算采用两个app来完成一件事,采用SharedPreferences来做数据交换,于是突然想验证一下Java层的权限设置会不会就是设置Linux下文件的权限,验证的结果是这样的. T ...

  5. 数据库语言(三):MySQL、PostgreSQL、JDBC

    MySQL MySQL资料很多,这里只给出一个在论坛博客中最常用的操作:分页 mysql> select pname from product limit 10,20; limit的第一个参数是 ...

  6. db2数据库Date相关函数

    1.db2可以通过SYSIBM.SYSDUMMY1.SYSIBM.DUAL获取寄存器中的值,也可以通过VALUES关键字获取寄存器中的值. SELECT 'HELLO DB2' FROM SYSIBM ...

  7. 【转】iOS学习之Autolayout(代码添加约束) -- 不错不错

    原文网址:http://www.cnblogs.com/HypeCheng/articles/4192154.html DECEMBER 07, 2013 学习资料 文章 Beginning Auto ...

  8. [Everyday Mathematics]20150106

    (1). 设 $f\in C[0,T]$, $g$ 是 $T$-周期函数, 试证: $$\bex \vlm{n}\int_0^T f(x)g(nx)\rd x=\frac{1}{T}\int_0^T ...

  9. HDU5777 domino (BestCoder Round #85 B) 思路题+排序

    分析:最终的结果肯定会分成若干个区间独立,这些若干个区间肯定是独立的(而且肯定是一边倒,左右都一样) 这样想的话,就是如何把这n-1个值分成 k份,使得和最小,那么就是简单的排序,去掉前k大的(注意l ...

  10. Web自动化框架之五一套完整demo的点点滴滴(excel功能案例参数化+业务功能分层设计+mysql数据存储封装+截图+日志+测试报告+对接缺陷管理系统+自动编译部署环境+自动验证false、error案例)

    标题很大,想说的很多,不知道从那开始~~直接步入正题吧 个人也是由于公司的人员的现状和项目的特殊情况,今年年中后开始折腾web自动化这块:整这个原因很简单,就是想能让自己偷点懒.也让减轻一点同事的苦力 ...