题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=4578

题目大意:n个数(初始为0)m个操作,操作类型有4种,操作1把区间的每个数+a,操作2把区间的每个数*a.,操作3把区间的每个数=a,操作4,查询区间每个数p次方的和(1<=p<=3)

解:

线段树解决,考虑的问题有两个:

1、赋值操作一定放在前面,然后有 先+后* 和 先*后+ 效果不一样

2、p次方和

对于问题一,采用先*后+的方式,这样在加入一个乘法标记的时候只用给之前的加标记乘上新标记的数即可

对于问题二,把(a+b)^2 和 (a+b)^3 展开,就知道怎么处理了

 /*
* Problem:
* Author: SHJWUDP
* Created Time: 2015/11/3 星期二 15:20:05
* File Name: 1001.cpp
* State:
* Memo:
*/
#include <iostream>
#include <cstdio>
#include <vector>
#include <cstring>
#include <algorithm>
#include <list> using namespace std; const int MOD=1e4+; struct SegmentTree {
struct Node {
vector<long long> sum;
vector<long long> delay;
Node():sum(), delay(){ delay[]=; }
void relax() {
for(auto & x : sum) x%=MOD;
for(auto & x : delay) x%=MOD;
}
};
int n;
vector<Node> c;
SegmentTree(int _n):n(_n),c(_n<<){}
#define lson l, m, rt<<1
#define rson m+1, r, rt<<1|1
void deal(Node & o, pair<int, int> p, int range) {
auto & d=o.delay;
long long b1=p.second, b2=b1*b1, b3=b2*b1;
switch(p.first) {
case :
{
long long a1=o.sum[], a2=o.sum[];
o.sum[]+=*a1*b2+*a2*b1+b3*range;
o.sum[]+=*a1*b1+b2*range;
o.sum[]+=b1*range;
d[]+=b1;
break;
}
case :
o.sum[]*=b3;
o.sum[]*=b2;
o.sum[]*=b1;
d[]*=b1;
d[]*=b1;
break;
case :
o.sum[]=b3*range;
o.sum[]=b2*range;
o.sum[]=b1*range;
d[]=; d[]=;
d[]=b1;
break;
}
o.relax();
}
void pushDown(int l, int m, int r, int rt) {
for(int i=; i>=; --i) {
if(!c[rt].delay[i]) continue;
if(i== && c[rt].delay[i]==) continue;
deal(c[rt<<], {i, c[rt].delay[i]}, m-l+);
deal(c[rt<<|], {i, c[rt].delay[i]}, r-m);
}
c[rt].delay={, , };
}
void pushUp(int rt) {
for(int i=; i<; ++i) {
c[rt].sum[i]=(c[rt<<].sum[i]+c[rt<<|].sum[i])%MOD;
}
}
void update(int L, int R, pair<int, int> x, int l, int r, int rt) {
if(L<=l && r<=R) {
deal(c[rt], x, r-l+);
} else {
int m=(l+r)>>;
pushDown(l, m, r, rt);
if(L<=m) update(L, R, x, lson);
if(m<R) update(L, R, x, rson);
pushUp(rt);
}
}
int query(int L, int R, int x, int l, int r, int rt) {
if(L<=l && r<=R) {
return c[rt].sum[x];
} else {
int m=(l+r)>>;
pushDown(l, m, r, rt);
int ret=;
if(L<=m) ret=query(L, R, x, lson);
if(m<R) ret=(ret+query(L, R, x, rson))%MOD;
return ret;
}
}
}; int main() {
#ifndef ONLINE_JUDGE
freopen("in", "r", stdin);
freopen("out", "w", stdout);
#endif
int n, m;
while(scanf("%d%d", &n, &m), n||m) {
SegmentTree st(n);
while(m--) {
int op, a, b, c;
scanf("%d%d%d%d", &op, &a, &b, &c);
--a; --b;
// cout<<"<----------------->"<<endl;
if(op==) {
printf("%d\n", st.query(a, b, c-, , st.n-, ));
} else {
st.update(a, b, {op-, c}, , st.n-, );
}
}
}
return ;
}

hdu4578 Transformation的更多相关文章

  1. HDU-4578 Transformation(线段树的多种区间操作)

    http://acm.hdu.edu.cn/showproblem.php?pid=4578 Time Limit: 15000/8000 MS (Java/Others)    Memory Lim ...

  2. 【HDU4578 Transformation】线段树

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=4578 题意:有一个序列,有四种操作: 1:区间[l,r]内的数全部加c. 2:区间[l,r]内的数全部 ...

  3. HDU4578 Transformation 线段树

    这个题让我重新学习了加 乘 在区间的操作 题解:http://blog.csdn.net/guognib/article/details/25324025?utm_source=tuicool& ...

  4. HDU4578 Transformation【线段树】

    <题目链接> <转载于 >>> > 题目大意: 有一个序列,有四种操作: 1:区间[l,r]内的数全部加c. 2:区间[l,r]内的数全部乘c. 3:区间[l ...

  5. HDU4578 Transformation (多操作线段树)

    传送门 终于过了这道题.. 要注意标记之间的影响,和add操作时更新求和的顺序. same 区间每个数设置为x标记 mult  区间每个数乘x标记 add  区间每个数加x标记 ①:当打same标记时 ...

  6. HDU4578 Transformation(多标记线段树)题解

    题意: 操作有:\(1\).区间都加\(a\):\(2\).区间都乘\(a\):\(3\).区间都重置成\(a\):\(4\).询问区间幂次和\(\sum_{i=l}^rnum[i]^p(p\in\{ ...

  7. Transformation(线段树+HDU4578+多种操作+鬼畜的代码)

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=4578 题目: 题意:n个数初始值为0,进行四种操作:1.将区间内的数字加c:2.将区间内的数字乘c:3 ...

  8. (七)Transformation和action详解-Java&Python版Spark

    Transformation和action详解 视频教程: 1.优酷 2.YouTube 什么是算子 算子是RDD中定义的函数,可以对RDD中的数据进行转换和操作. 算子分类: 具体: 1.Value ...

  9. 线性分式变换(linear fractional transformation)

    线性分式变换(linear fractional transformation)的名称来源于其定义的形式:(ax+b)/(cx+d),其中分子分母是线性的,然后最外层是一个分式形式,所以叫做这个名字, ...

随机推荐

  1. MAGIC XPA最新版本Magic xpa 2.4c Release Notes

    New Features, Feature Enhancements and Behavior ChangesSubforms – Behavior Change for Unsupported Ta ...

  2. Android 用HorizontalScrollView实现ListView的Item滑动删除 ,滑动错乱 冲突

    用HorizontalScrollView实现类似微信的滑动删除 测试于:Android2.2+ 对于Android来说按键操作已经在减少,越来越多的手势操作层出不穷,今天介绍一款LIstView的I ...

  3. python平台跨平台开发

    有助于跨平台开发的 os 模块属性: linesep  用于在文件中分隔行的字符串 sep  用来分隔文件路径名的字符串 pathsep 用于分隔文件路径的字符串 curdir  当前工作目录的字符串 ...

  4. 用OSSIM轻松分析网络设备日志

    用OSSIM轻松分析网络设备日志 基于插件的日志收集与处理模式,使得用户可以轻松的利用OSSIM来分析异构网络环境下的各种网络设备日志,下面展示一些硬件设备日志的实例,我们在RAW LOG界面里,搜索 ...

  5. 使用yum安装应用程序时候,报错:[Errno 14] PYCURL ERROR 7 - "Failed to connect to 2001:da8:8000:6023::230: 网络不可达"

    使用yum安装应用程序时候,报错:[Errno 14] PYCURL ERROR 7 - "Failed to connect to 2001:da8:8000:6023::230: 网络不 ...

  6. arcgis_engine_c++_runtime_r6034_error

    在启动项目中添加app.manifest文件 <?xml version="1.0" encoding="utf-8"?> <asmv1:as ...

  7. backup1

    string _imgpath1 = WebConfigurationManager.AppSettings["IMGPATH1"].ToString(); string outp ...

  8. String类常用方法

    1.String类的特点,字符串一旦被初始化就不会被改变. 2.String对象定义的两种方式 ①String s = "affdf";这种定义方式是在字符串常量池中创建一个Str ...

  9. C语言中extern的用法

    0x01 extern用在变量或函数的声明前,用来说明“此变量/函数是在别处定义的,要在此处引用”. 0x02 extern修饰变量的声明. 举例:若a.c中需引用b.c中的变量int v,可以在a. ...

  10. MVC中的@符号

    1: @if (@Model.DepositList != null) { } 2: @if (@Model.DepositList != null) { foreach (Deposit_ViewM ...