线段树 I - Transformation 加乘优先级
I - Transformation
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 题目思路:
这个题目是一个裸的线段树,有四种操作,
第一种就是区间更新,在每一个数值+c
第二种就是每一个位置*c
第三种就是把每一个位置的数更新成c
第四种求每一个数的c次方的和
前面三种就是普通的线段树,最后一种因为c比较小,最大只有三所以就在结构体里面枚举三种情况就可以了。
第一种和第二张要设置两个lazy标志,第三种也要设置,但是如果第三种成立则之前的lazy标志都要删去,一共有了三种lazy标志。
#include <stdio.h>
#include <string.h>
#include <iostream>
#include <algorithm>
#include <vector>
#include <queue>
#include <set>
#include <map>
#include <string>
#include <math.h>
#include <stdlib.h>
using namespace std;
const int MOD = ;
const int MAXN = ;
struct Node
{
int l,r;
int sum1,sum2,sum3;
int lazy1,lazy2,lazy3;
}segTree[MAXN*];
void build(int i,int l,int r)
{
segTree[i].l = l;
segTree[i].r = r;
segTree[i].sum1 = segTree[i].sum2 = segTree[i].sum3 = ;
segTree[i].lazy1 = segTree[i].lazy3 = ;
segTree[i].lazy2 = ;
int mid = (l+r)/;
if(l == r)return;
build(i<<,l,mid);
build((i<<)|,mid+,r);
}
void push_up(int i)
{
if(segTree[i].l == segTree[i].r)
return;
segTree[i].sum1 = (segTree[i<<].sum1 + segTree[(i<<)|].sum1)%MOD;
segTree[i].sum2 = (segTree[i<<].sum2 + segTree[(i<<)|].sum2)%MOD;
segTree[i].sum3 = (segTree[i<<].sum3 + segTree[(i<<)|].sum3)%MOD; } void push_down(int i)
{
if(segTree[i].l == segTree[i].r) return;
if(segTree[i].lazy3 != )
{
segTree[i<<].lazy3 = segTree[(i<<)|].lazy3 = segTree[i].lazy3;
segTree[i<<].lazy1 = segTree[(i<<)|].lazy1 = ;
segTree[i<<].lazy2 = segTree[(i<<)|].lazy2 = ;
segTree[i<<].sum1 = (segTree[i<<].r - segTree[i<<].l + )*segTree[i<<].lazy3%MOD;
segTree[i<<].sum2 = (segTree[i<<].r - segTree[i<<].l + )*segTree[i<<].lazy3%MOD*segTree[i<<].lazy3%MOD;
segTree[i<<].sum3 = (segTree[i<<].r - segTree[i<<].l + )*segTree[i<<].lazy3%MOD*segTree[i<<].lazy3%MOD*segTree[i<<].lazy3%MOD;
segTree[(i<<)|].sum1 = (segTree[(i<<)|].r - segTree[(i<<)|].l + )*segTree[(i<<)|].lazy3%MOD;
segTree[(i<<)|].sum2 = (segTree[(i<<)|].r - segTree[(i<<)|].l + )*segTree[(i<<)|].lazy3%MOD*segTree[(i<<)|].lazy3%MOD;
segTree[(i<<)|].sum3 = (segTree[(i<<)|].r - segTree[(i<<)|].l + )*segTree[(i<<)|].lazy3%MOD*segTree[(i<<)|].lazy3%MOD*segTree[(i<<)|].lazy3%MOD;
segTree[i].lazy3 = ;
}
if(segTree[i].lazy1 != || segTree[i].lazy2 != )
{
segTree[i<<].lazy1 = ( segTree[i].lazy2*segTree[i<<].lazy1%MOD + segTree[i].lazy1 )%MOD;
segTree[i<<].lazy2 = segTree[i<<].lazy2*segTree[i].lazy2%MOD;
int sum1,sum2,sum3;
sum1 = (segTree[i<<].sum1*segTree[i].lazy2%MOD + (segTree[i<<].r - segTree[i<<].l + )*segTree[i].lazy1%MOD)%MOD;
sum2 = (segTree[i].lazy2 * segTree[i].lazy2 % MOD * segTree[i<<].sum2 % MOD + *segTree[i].lazy1*segTree[i].lazy2%MOD * segTree[i<<].sum1%MOD + (segTree[i<<].r - segTree[i<<].l + )*segTree[i].lazy1%MOD*segTree[i].lazy1%MOD)%MOD;
sum3 = segTree[i].lazy2 * segTree[i].lazy2 % MOD * segTree[i].lazy2 % MOD * segTree[i<<].sum3 % MOD;
sum3 = (sum3 + *segTree[i].lazy2 % MOD * segTree[i].lazy2 % MOD * segTree[i].lazy1 % MOD * segTree[i<<].sum2) % MOD;
sum3 = (sum3 + *segTree[i].lazy2 % MOD * segTree[i].lazy1 % MOD * segTree[i].lazy1 % MOD * segTree[i<<].sum1) % MOD;
sum3 = (sum3 + (segTree[i<<].r - segTree[i<<].l + )*segTree[i].lazy1%MOD * segTree[i].lazy1 % MOD * segTree[i].lazy1 % MOD) % MOD;
segTree[i<<].sum1 = sum1;
segTree[i<<].sum2 = sum2;
segTree[i<<].sum3 = sum3;
segTree[(i<<)|].lazy1 = ( segTree[i].lazy2*segTree[(i<<)|].lazy1%MOD + segTree[i].lazy1 )%MOD;
segTree[(i<<)|].lazy2 = segTree[(i<<)|].lazy2 * segTree[i].lazy2 % MOD;
sum1 = (segTree[(i<<)|].sum1*segTree[i].lazy2%MOD + (segTree[(i<<)|].r - segTree[(i<<)|].l + )*segTree[i].lazy1%MOD)%MOD;
sum2 = (segTree[i].lazy2 * segTree[i].lazy2 % MOD * segTree[(i<<)|].sum2 % MOD + *segTree[i].lazy1*segTree[i].lazy2%MOD * segTree[(i<<)|].sum1%MOD + (segTree[(i<<)|].r - segTree[(i<<)|].l + )*segTree[i].lazy1%MOD*segTree[i].lazy1%MOD)%MOD;
sum3 = segTree[i].lazy2 * segTree[i].lazy2 % MOD * segTree[i].lazy2 % MOD * segTree[(i<<)|].sum3 % MOD;
sum3 = (sum3 + *segTree[i].lazy2 % MOD * segTree[i].lazy2 % MOD * segTree[i].lazy1 % MOD * segTree[(i<<)|].sum2) % MOD;
sum3 = (sum3 + *segTree[i].lazy2 % MOD * segTree[i].lazy1 % MOD * segTree[i].lazy1 % MOD * segTree[(i<<)|].sum1) % MOD;
sum3 = (sum3 + (segTree[(i<<)|].r - segTree[(i<<)|].l + )*segTree[i].lazy1%MOD * segTree[i].lazy1 % MOD * segTree[i].lazy1 % MOD) % MOD;
segTree[(i<<)|].sum1 = sum1;
segTree[(i<<)|].sum2 = sum2;
segTree[(i<<)|].sum3 = sum3;
segTree[i].lazy1 = ;
segTree[i].lazy2 = ; }
}
void update(int i,int l,int r,int type,int c)
{
if(segTree[i].l == l && segTree[i].r == r)
{
c %= MOD;
if(type == )
{
segTree[i].lazy1 += c;
segTree[i].lazy1 %= MOD;
segTree[i].sum3 = (segTree[i].sum3 + *segTree[i].sum2%MOD*c%MOD + *segTree[i].sum1%MOD*c%MOD*c%MOD + (segTree[i].r - segTree[i].l + )*c%MOD*c%MOD*c%MOD)%MOD;
segTree[i].sum2 = (segTree[i].sum2 + *segTree[i].sum1%MOD*c%MOD + (segTree[i].r - segTree[i].l + )*c%MOD*c%MOD)%MOD;
segTree[i].sum1 = (segTree[i].sum1 + (segTree[i].r - segTree[i].l + )*c%MOD)%MOD;
}
else if(type == )
{
segTree[i].lazy1 = segTree[i].lazy1*c%MOD;
segTree[i].lazy2 = segTree[i].lazy2*c%MOD;
segTree[i].sum1 = segTree[i].sum1*c%MOD;
segTree[i].sum2 = segTree[i].sum2*c%MOD*c%MOD;
segTree[i].sum3 = segTree[i].sum3*c%MOD*c%MOD*c%MOD;
}
else
{
segTree[i].lazy1 = ;
segTree[i].lazy2 = ;
segTree[i].lazy3 = c%MOD;
segTree[i].sum1 = c*(segTree[i].r - segTree[i].l + )%MOD;
segTree[i].sum2 = c*(segTree[i].r - segTree[i].l + )%MOD*c%MOD;
segTree[i].sum3 = c*(segTree[i].r - segTree[i].l + )%MOD*c%MOD*c%MOD;
}
return;
}
push_down(i);
int mid = (segTree[i].l + segTree[i].r)/;
if(r <= mid)update(i<<,l,r,type,c);
else if(l > mid)update((i<<)|,l,r,type,c);
else
{
update(i<<,l,mid,type,c);
update((i<<)|,mid+,r,type,c);
}
push_up(i);
}
int query(int i,int l,int r,int p)
{
if(segTree[i].l == l && segTree[i].r == r)
{
if(p == )return segTree[i].sum1;
else if(p== )return segTree[i].sum2;
else return segTree[i].sum3;
}
push_down(i);
int mid = (segTree[i].l + segTree[i].r )/;
if(r <= mid)return query(i<<,l,r,p);
else if(l > mid)return query((i<<)|,l,r,p);
else return (query(i<<,l,mid,p)+query((i<<)|,mid+,r,p))%MOD;
} int main()
{
//freopen("in.txt","r",stdin);
//freopen("out.txt","w",stdout);
int n,m;
while(scanf("%d%d",&n,&m) == )
{
if(n == && m == )break;
build(,,n);
int type,x,y,c;
while(m--)
{
scanf("%d%d%d%d",&type,&x,&y,&c);
if(type == )printf("%d\n",query(,x,y,c));
else update(,x,y,type,c);
}
}
return ;
}
#include <stdio.h>
#include <algorithm>
#include <string.h>
#include <queue>
#include <math.h>
#define LL long long
using namespace std;
const LL MAX = 1e6 + ;
LL INF = 1e8;
LL MOD = ; LL PowerMod(LL a, LL b)
{
LL ans = ;
a = a % MOD;
while(b > ) {
if(b % == )
ans = (ans * a) % MOD;
b = b / ;
a = (a * a) % MOD;
}
return ans;
} LL a[MAX];
LL lazy[MAX << ][]; void PushDown(LL rt){
if(lazy[rt][] != -){
lazy[rt << ][] = lazy[rt << | ][] = lazy[rt][] % MOD;
lazy[rt << ][] = lazy[rt << | ][] = ;
lazy[rt << ][] = lazy[rt << | ][] = ;
lazy[rt][] = -;
} if(lazy[rt][] != ){
if(lazy[rt << ][] != -){
lazy[rt << ][] *= lazy[rt][];
lazy[rt << ][] %= MOD;
} else{
PushDown(rt << );
lazy[rt << ][] *= lazy[rt][];
lazy[rt << ][] %= MOD;
} if(lazy[rt << | ][] != -){
lazy[rt << | ][] *= lazy[rt][];
lazy[rt << | ][] %= MOD;
} else{
PushDown(rt << | );
lazy[rt << | ][] *= lazy[rt][];
lazy[rt << | ][] %= MOD;;
}
lazy[rt][] = ;
} if(lazy[rt][] != ){
if(lazy[rt << ][] != -){
lazy[rt << ][] += lazy[rt][];
lazy[rt << ][] %= MOD;
} else{
PushDown(rt << );
lazy[rt << ][] += lazy[rt][];
lazy[rt << ][] %= MOD;
} if(lazy[rt << | ][] != -){
lazy[rt << | ][] += lazy[rt][];
lazy[rt << | ][] %= MOD;
} else{
PushDown(rt << | );
lazy[rt << | ][] += lazy[rt][];
lazy[rt << | ][] %= MOD;
}
lazy[rt][] = ;
}
} void Build(LL l, LL r, LL rt){
lazy[rt][] = -;
lazy[rt][] = ;
lazy[rt][] = ;
if(l == r){
lazy[rt][] = ;
return ;
}
LL m = (l + r) >> ;
Build(l, m, rt << );
Build(m + , r, rt << | );
} LL L, R, C;
void Update0(LL l, LL r, LL rt){
if(L <= l && r <= R){
lazy[rt][] = C;
lazy[rt][] %= MOD;
lazy[rt][] = ;
lazy[rt][] = ;
return ;
}
PushDown(rt);
LL m = (l + r) >> ;
if(L <= m){
Update0(l, m, rt << );
}
if(R > m){
Update0(m + , r, rt << | );
}
} void Update1(LL l, LL r, LL rt){
if(L <= l && r <= R){
if(lazy[rt][] != -){
lazy[rt][] *= C;
lazy[rt][] %= MOD;
} else{
PushDown(rt);
lazy[rt][] *= C;
lazy[rt][] %= MOD;
}
return ;
} LL m = (l + r) >> ;
PushDown(rt);
if(L <= m){
Update1(l, m, rt << );
}
if(R > m){
Update1(m + , r, rt << | );
}
} void Update2(LL l, LL r, LL rt){
if(L <= l && r <= R){
if(lazy[rt][] != -){
lazy[rt][] += C;
lazy[rt][] %= MOD;
} else{
PushDown(rt);
lazy[rt][] += C;
lazy[rt][] %= MOD;
}
return ;
} LL m = (l + r) >> ;
PushDown(rt);
if(L <= m){
Update2(l, m, rt << );
}
if(R > m){
Update2(m + , r, rt << | );
}
} LL ans = ;
void Query(LL l, LL r, LL rt){
if(L <= l && r <= R && lazy[rt][] != -){
ans = ans + (r - l + ) * PowerMod(lazy[rt][], C);
ans %= MOD;
return ;
} PushDown(rt);
LL m = (l + r) >> ;
if(L <= m){
Query(l, m, rt << );
}
if(R > m){
Query(m + , r, rt << | );
}
}
int main(int argc, char const *argv[])
{
LL n, m; while(){
scanf("%lld%lld", &n, &m);
if(n == && m == ){
break;
}
Build(, n, );
while(m--){
LL op;
scanf("%lld%lld%lld%lld", &op, &L, &R, &C);
if(op == ){
Update2(, n, );
} else if(op == ){
Update1(, n, );
} else if(op == ){
Update0(, n, );
} else{
ans = ;
Query(, n, );
printf("%lld\n", ans);
}
}
}
return ;
}
线段树 I - Transformation 加乘优先级的更多相关文章
- 线段树_区间加乘(洛谷P3373模板)
题目描述 如题,已知一个数列,你需要进行下面三种操作: 1.将某区间每一个数乘上x 2.将某区间每一个数加上x 3.求出某区间每一个数的和 输入格式: 第一行包含三个整数N.M.P,分别表示该数列数字 ...
- UESTC-1057 秋实大哥与花(线段树+成段加减+区间求和)
秋实大哥与花 Time Limit: 3000/1000MS (Java/Others) Memory Limit: 65535/65535KB (Java/Others) Submit St ...
- bzoj 1835 [ZJOI2010]base 基站选址(DP+线段树)
[题目链接] http://www.lydsy.com/JudgeOnline/problem.php?id=1835 [题意] 有n个村庄,每个村庄位于d[i],要求建立不多于k个基站,在第i个村庄 ...
- HDU5669 Road 分层最短路+线段树建图
分析:(官方题解) 首先考虑暴力,显然可以直接每次O(n^2) 的连边,最后跑一次分层图最短路就行了. 然后我们考虑优化一下这个连边的过程 ,因为都是区间上的操作,所以能够很明显的想到利用线段树来维 ...
- bzoj 2482: [Spoj GSS2] Can you answer these queries II 线段树
2482: [Spoj1557] Can you answer these queries II Time Limit: 20 Sec Memory Limit: 128 MBSubmit: 145 ...
- 2018 UESTC 线段树专题
A - 一棵简单的线段树 A[1...n]初始全为0. 1. 给两个数p 和 x(1≤p≤n),单点更新 A[p] <- x 2. 给两个数L和R (1≤L<R≤n), L到R区间里这几 ...
- BZOJ.4825.[AHOI/HNOI2017]单旋(线段树)
BZOJ LOJ 洛谷 这题不难啊,我怎么就那么傻,拿随便一个节点去模拟.. 我们只需要能够维护,将最小值或最大值转到根.模拟一下发现,对于最小值,它的右子树深度不变(如果存在),其余节点深度全部\( ...
- [线段树]picture
PICTURE 题目描述 N(N<5000) 张矩形的海报,照片和其他同样形状的图片贴在墙上.它们的边都是垂直的或水平的.每个矩形可以部分或者全部覆盖其他矩形.所有的矩形组成的集合的轮廓称为周长 ...
- bzoj 2243: [SDOI2011]染色 (树链剖分+线段树 区间合并)
2243: [SDOI2011]染色 Time Limit: 20 Sec Memory Limit: 512 MBSubmit: 9854 Solved: 3725[Submit][Status ...
随机推荐
- nmon 的下一代工具 njmon
njmon njmon = nmon + JSON format + real-time push to a stats database + instant graphing of "al ...
- ASE课程总结 by 朱玉影
收获: 最大的收获应该就是对待选题要慎重吧,虽然前期做了一下调研,但是还是不够,所以到最后我们的项目才会不能公开发布,项目中间也是波折不断,导致我们走了很多弯路,浪费了很多时间吧.选题一定要慎重,慎重 ...
- 二分例题 51nod
例题1 1010 只包含因子2 3 5的数 http://www.51nod.com/Challenge/Problem.html#problemId=1010 K的因子中只包含2 3 5.满足条件的 ...
- api测试用例(编写思路)
在API的自动化测试维度中,测试维度分为两个维度,一个是单独的对API的验证,客户端发送一个请求后,服务端得到客户端的请求并且响应回复给客户端: 另外一个维度是基于业务场景的测试,基于业务场景的也就是 ...
- 小小小小小flag
2020:300道题 小小小小小flag 150红题 100道橙题 50道黄题 努力变强!加油 我的主页: 主页https://www.luogu.com.cn/user/306734 谢谢大家,目前 ...
- 多线程高并发编程(6) -- Semaphere、Exchanger源码分析
一.Semaphere 1.概念 一个计数信号量.在概念上,信号量维持一组许可证.如果有必要,每个acquire()都会阻塞,直到许可证可用,然后才能使用它.每个release()添加许可证,潜在地释 ...
- 6.表单提交,input键盘变搜索,有关自定义属性input操作
1.键盘变搜索 1.) 在form 上加action="#", 2.)input type=search, 3.)此时会提交到 #,需要再添加一个input display=non ...
- leetcode-0617 合并二叉树
题目地址https://leetcode-cn.com/problems/merge-two-binary-trees/ 1.递归解法 递归的话我们首先需要递归的终止条件,对于本题而言,递归的终止条件 ...
- VideoView--简单获取进度条的方法
使用MediaController类就可以简单的把视频中的进度条加进去 实例: 现在布局哪里放一个VideoView,然后: videoView = (VideoView) findViewById( ...
- VideoView--简单的设置全屏幕播放
我说的最主要的是要在布局哪里设置一下,如: <com.example.mypalyer.fullScreen android:id="@+id/videoView1& ...