Yuanfang is puzzled with the question below: 
There are n integers, a 1, a 2, …, a n. The initial values of them are 0. There are four kinds of operations. 
Operation 1: Add c to each number between a x and a y inclusive. In other words, do transformation a k<---a k+c, k = x,x+1,…,y. 
Operation 2: Multiply c to each number between a x and a y inclusive. In other words, do transformation a k<---a k×c, k = x,x+1,…,y. 
Operation 3: Change the numbers between a x and a y to c, inclusive. In other words, do transformation a k<---c, k = x,x+1,…,y. 
Operation 4: Get the sum of p power among the numbers between a x and a y inclusive. In other words, get the result of a x p+a x+1 p+…+a y p
Yuanfang has no idea of how to do it. So he wants to ask you to help him. 

InputThere are no more than 10 test cases. 
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. 
OutputFor each operation 4, output a single integer in one line representing the result. The answer may be quite large. You just need to calculate the remainder of the answer when divided by 10007.Sample Input

5 5
3 3 5 7
1 2 4 4
4 1 5 2
2 2 5 8
4 3 5 3
0 0

Sample Output

307
7489 分析;本题极其巧妙地运用了线段树懒惰标记的功能,由于本题的特殊性,一开始每个元素都是相等的,而且操作也是对于区间进行的,这就会导致很多相同的元素挨在一起,形成一个个区间,为懒惰标记发挥作用和批量操作创造条件;
flag(懒惰标记)表示该区间的元素是否是相同的,v表示这个区间里面元素的值;
然后再通过合理的pushdown和pushup操作便可以快速的实现对于区间的统计工作。这比网上其他的思路(统计sum1,sum2, sum3.....)快很多。 代码:
 #include <bits/stdc++.h>
using namespace std;
const int maxn = 1e5 + ;
const int mod = ;
struct node
{
int l, r;
int v;
bool flag;
}t[maxn << ];
int n, m; void pushup(int tar)
{
if (t[tar << ].flag && t[tar << | ].flag && t[tar << ].v == t[tar << | ].v)
t[tar].flag = true, t[tar].v = t[tar << ].v;
else t[tar].flag = false;
} void pushdown(int tar)
{
if (t[tar].flag)
{
t[tar << ].flag = t[tar << | ].flag = true;
t[tar << ].v = t[tar << | ].v = t[tar].v;
t[tar].flag = false;
}
} void build(int l, int r, int tar)
{
t[tar].l = l, t[tar].r = r, t[tar].v = , t[tar].flag = true;
if (l == r) return;
int mid = (l + r) >> ;
build(l, mid, tar << );
build(mid + , r, tar << | );
} void update(int ope, int l, int r, int v, int tar)
{
if (t[tar].l == l && t[tar].r == r && t[tar].flag == true)
{
if (ope == ) t[tar].v += v;
else if (ope == ) t[tar].v *= v;
else t[tar].v = v;
t[tar].v %= mod;
return;
}
pushdown(tar);
int mid = (t[tar].l + t[tar].r) >> ;
if (r <= mid) update(ope, l, r, v, tar << );
else if (l > mid) update(ope, l, r, v, tar << | );
else update(ope, l, mid, v, tar << ), update(ope, mid + , r, v, tar << | );
pushup(tar);
} int query(int l, int r, int v, int tar)
{
if (t[tar].l == l && t[tar].r == r && t[tar].flag == true)
{
int res = ;
for (int i = ; i < v; i++)
res *= t[tar].v, res %= mod;
return res * (t[tar].r - t[tar].l + ) % mod;
}
pushdown(tar);
int mid = (t[tar].l + t[tar].r) >> ;
if (r <= mid) return query(l, r, v, tar << );
else if (l > mid) return query(l, r, v, tar << | );
else return (query(l, mid, v, tar << ) + query(mid + , r, v, tar << | )) % mod;
} int main()
{
int ope, x, y, c; while (cin >> n >> m && n && m)
{
build(, n, );
while (m--)
{
scanf("%d%d%d%d", &ope, &x, &y, &c);
if (ope != )
update(ope, x, y, c, );
else cout << query(x, y, c, ) << endl;
}
}
}

Transformation HDU - 4578(线段树——懒惰标记的妙用)的更多相关文章

  1. K - Transformation HDU - 4578 线段树经典题(好题)

    题意:区间  加   变成定值 乘  区间查询:和 平方和 立方和 思路:超级超级超级麻烦的一道题  设3个Lazy 标记分别为  change 改变mul乘 add加  优先度change>m ...

  2. hdu 4578 线段树(标记处理)

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

  3. 【HDU】4092 Nice boat(多校第四场1006) ——线段树 懒惰标记

    Nice boat Time Limit: 30000/15000 MS (Java/Others)    Memory Limit: 131072/131072 K (Java/Others) To ...

  4. HDU 4578 线段树玄学算法?

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

  5. Codeforces 444C 线段树 懒惰标记

    前天晚上的CF比赛div2的E题,很明显一个线段树,当时还在犹豫复杂度的问题,因为他是区间修改和区间查询,肯定是要用到懒惰标记. 然后昨天真的是给这道题跪了,写了好久好久,...我本来是写了个add标 ...

  6. HDU 4578 线段树复杂题

    题目大意: 题意:有一个序列,有四种操作: 1:区间[l,r]内的数全部加c. 2:区间[l,r]内的数全部乘c. 3:区间[l,r]内的数全部初始为c. 4:询问区间[l,r]内所有数的P次方之和. ...

  7. HDU - 4578 线段树+三重操作

    这道题自己写了很久,还是没写出来,也看了很多题解,感觉多数还是看的迷迷糊糊,最后面看到一篇大佬的才感觉恍然大悟. 先上一篇大佬的题解:https://blog.csdn.net/aqa20372995 ...

  8. hdu 4578 线段树 ****

    链接:点我  1

  9. hdu 3954 线段树 (标记)

    Level up Time Limit: 10000/3000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) Total ...

随机推荐

  1. @ApiImplicitParam注解

    @Api:用在请求的类上,表示对类的说明 tags="说明该类的作用,可以在UI界面上看到的注解" value="该参数没什么意义,在UI界面上也看到,所以不需要配置&q ...

  2. C++学习书籍推荐《Effective C++ 第三版》下载

    百度云及其他网盘下载地址:点我 编辑推荐 <Effective C++:改善程序与设计的55个具体做法(第3版)(中文版)(双色)>前两个版本抓住了全世界无数程序员的目光.原因十分明显:S ...

  3. tomcat问题解决

    tomcat问题解决 运行tomcat环境下,idea中出现 error running 项目名address localhost1099 is already in use 的时候,如何解决? 1, ...

  4. 小白教程 Java web maven项目Windows下部署阿里云服务器全过程(买服务器,打包项目,连接服务器,配置服务器,部署项目)

    -------------首先:购买服务器---------------- Step1: 在https://www.aliyun.com/?utm_content=se_1043015注册登录阿里云 ...

  5. NET多线程之进程间同步锁Mutex

    Mutex类似于lock.Monitor,都是为了解决多线程环境下,资源竞争导致的访问顺序问题.常见资源竞争有以下情况: 1.单例,如何确保单例: 2.IO文件操作,如果同时又多个线程访问同一个文件会 ...

  6. python实现DFA模拟程序(附java实现代码)

    DFA(确定的有穷自动机) 一个确定的有穷自动机M是一个五元组: M=(K,∑,f,S,Z) K是一个有穷集,它的每个元素称为一个状态. ∑是一个有穷字母表,它的每一个元素称为一个输入符号,所以也陈∑ ...

  7. .NET CORE上传文件到码云仓库【搭建自己的图床】

    .NET CORE上传文件到码云仓库[搭建自己的图床] 先建一个公共仓库(随意提交一个README文件或者.gitignore文件保证master分支的存在),然后到gitee的个人设置页面找到[私人 ...

  8. 入职两个月,WPF开发感想

    1 .新工作,新开始 2.WPF初次接触以及学习MVVM开发模式 3.后台数据操作,ORACLE 存储过程(边做边学) 4.总结 4.1工作开发中的小问题 ,遇到的坑:  4.2 解决的问题,学校到的 ...

  9. 将Ueditor文件上传至OSS

    前人已经将ueditor集成了oss,本次是作为记录 1:点击到下载页面 下载并按照文档安装 2:将 com.zip(在UEditor-for-aliyun-OSS-master\ueditor\sr ...

  10. C语言入门9-1-分类函数

    分类函数 ASCII字符可以分为英文字母.数字.控制字符.空白字符.大小写字母以及标点符号,分类是指对字符进行属性判定,判断字符属于哪些范畴,这些属性的判定在程序中非常常见,尤其是通信协议的字符处理部 ...