线段树上的多操作。。。

题目大意:

树上 的初始值为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. hdu 携程全球数据中心建设 (球面距离 + 最小生成树)

    题目 #include <iostream> #include <cstdio> #include <cstring> #include <cstdlib&g ...

  2. 计算几何基础——矢量和叉积 && 叉积、线段相交判断、凸包(转载)

    转载自 http://blog.csdn.net/william001zs/article/details/6213485 矢量 如果一条线段的端点是有次序之分的话,那么这种线段就称为 有向线段,如果 ...

  3. 函数ut_2_log

    计算某个数的对数(最大的) 例如 16 计算后为 4 2的4次方为16 例如15 计算后为3 2的3次方为8 /******************************************** ...

  4. Spring MVC定义拦截器

    拦截器: package sy.Interceptor; import javax.servlet.http.HttpServletRequest; import javax.servlet.http ...

  5. BZOJ 1610 连线游戏

    BZOJ不允许除以0. #include<iostream> #include<cstdio> #include<cstring> #include<cstd ...

  6. Darwin Streaming Server 简介

    Darwin Streaming Server     概要 Darwin Streaming Server简称DSS.DSS是Apple公司提供的开源实时流媒体播放服务器程序.整个程序使用C++编写 ...

  7. 如何借助于UML完成我们对系统的设计?谈谈我的理解

    首先要说的是我对面向对象的理解,以及设计类的依据: http://www.cnblogs.com/xinchrome/p/4904931.html 理解了这篇文章,也就理解了现在要说的. 在面向对象编 ...

  8. session服务器Nginx+Tomcat+Memcached集群Session共享

    cookie是怎样工作的? 例如,我们创立了一个名字为login的Cookie来包含访问者的信息,创立Cookie时,服务器端的Header如下面所示,这里假设访问者的注册名是“Michael Jor ...

  9. CentOS SVN服务器安装配置小记

    SVN的安装 安装很简单,尤其对于CentOS这种,直接: # yum install subversion# yum install mod_dav_svn 不同发行版的Package安装方法参见h ...

  10. 《C++ Primer 4th》读书笔记 第4章-数组和指针

    原创文章,转载请注明出处: http://www.cnblogs.com/DayByDay/p/3911573.html