题目链接: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. 转:C# 中 MSCHART 饼状图显示百分比

    转自:http://blog.sina.com.cn/s/blog_51beaf0e0100yffo.html 1)显示百分比 Chart1.Series["Series1"].L ...

  2. 魅蓝note2在ubuntu14.04下mtp模式无法自动mount的解决方法

    是因为新机型没在列表里的原因. 处理方法如下: As far as I know, MTP works fine in Trusty. You can try this: Uncomment #use ...

  3. 转:SAAS 测试

    基于SaaS云计算网络性能测试指标研究 来源:中国软件评测中心  作者:马子明  投稿时间:2011-04-02 1.基于SaaS的云计算 SaaS(Software as a Service,软件即 ...

  4. DataURL详解--转自格桑blog

    DataURI详解 Posted on 2013 年 09 月 09 日 by admin DataURI,不算新东西,却一直没用过,前些日子在webapp中用了点DataURI,就做了下相关的了解, ...

  5. setFeatureInt、android 自定义标题栏

    Android 自带的toolbar 往往不能很好的的满足我们的个性化要求.因此我们经常使用自定的的标题栏.而Android系统本身也允许我们自定以标题栏. 记录一下,自定义标题栏常遇到的问题.先上效 ...

  6. Ubuntu更改鼠标灵敏度

    需要命令:xinput 清自行用 man xinput 查询 xinput 帮助文档 1.插入鼠标,打开终端,输入命令:xinput 查询当前已挂在设备 2.拔出鼠标,打开终端,再输入命令:xinpu ...

  7. 仿google art图片预览算法及demo(iphone/安卓版本)

    演示地址:用手机扫描二维码(手机端浏览) 功能:双击放大,单指操作拖动,双指操作放大缩小.

  8. Google黑板报: 数学之美系列(网上找的原链接)

    转载地址:http://blog.sina.com.cn/s/blog_47cccb02010009u0.html 系列一 -- 统计语言模型 http://googlechinablog.com/2 ...

  9. python已字典为元素的数组排序

    dict = [ {','name':'b'}, {','name':'c'}, {','name':'a'}, {','name':'g'}, {','name':'f'} ] dict.sort( ...

  10. MySQL 5.7 Command Line Client输入密码后闪退和windows下mysql忘记root密码的解决办法

    MySQL 5.7 Command Line Client输入密码后闪退的问题: 问题分析: 1.查看mysql command line client默认执行的一些参数.方法:开始->所有程序 ...