I - Transformation

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 题目思路:
这个题目是一个裸的线段树,有四种操作,
第一种就是区间更新,在每一个数值+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 加乘优先级的更多相关文章

  1. 线段树_区间加乘(洛谷P3373模板)

    题目描述 如题,已知一个数列,你需要进行下面三种操作: 1.将某区间每一个数乘上x 2.将某区间每一个数加上x 3.求出某区间每一个数的和 输入格式: 第一行包含三个整数N.M.P,分别表示该数列数字 ...

  2. UESTC-1057 秋实大哥与花(线段树+成段加减+区间求和)

    秋实大哥与花 Time Limit: 3000/1000MS (Java/Others)     Memory Limit: 65535/65535KB (Java/Others) Submit St ...

  3. bzoj 1835 [ZJOI2010]base 基站选址(DP+线段树)

    [题目链接] http://www.lydsy.com/JudgeOnline/problem.php?id=1835 [题意] 有n个村庄,每个村庄位于d[i],要求建立不多于k个基站,在第i个村庄 ...

  4. HDU5669 Road 分层最短路+线段树建图

    分析:(官方题解) 首先考虑暴力,显然可以直接每次O(n^2) ​的连边,最后跑一次分层图最短路就行了. 然后我们考虑优化一下这个连边的过程 ,因为都是区间上的操作,所以能够很明显的想到利用线段树来维 ...

  5. 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 ...

  6. 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区间里这几 ...

  7. BZOJ.4825.[AHOI/HNOI2017]单旋(线段树)

    BZOJ LOJ 洛谷 这题不难啊,我怎么就那么傻,拿随便一个节点去模拟.. 我们只需要能够维护,将最小值或最大值转到根.模拟一下发现,对于最小值,它的右子树深度不变(如果存在),其余节点深度全部\( ...

  8. [线段树]picture

    PICTURE 题目描述 N(N<5000) 张矩形的海报,照片和其他同样形状的图片贴在墙上.它们的边都是垂直的或水平的.每个矩形可以部分或者全部覆盖其他矩形.所有的矩形组成的集合的轮廓称为周长 ...

  9. bzoj 2243: [SDOI2011]染色 (树链剖分+线段树 区间合并)

    2243: [SDOI2011]染色 Time Limit: 20 Sec  Memory Limit: 512 MBSubmit: 9854  Solved: 3725[Submit][Status ...

随机推荐

  1. editplus 怎么替换为换行

    到editplus 的搜索 菜单中,选择替换,记住 这边如果是简单的一些 通用字符 替换可以直接替换,如果是一些特殊的字符 那必须选择 替换框左下中间的 “正则表达式”,即把这个“正则表达式” 前边的 ...

  2. win10安装docker,VSCode管理docker

    背景 docker:随着技术的不断迭代,开发环境的配置与部署越来越重要.Docker 是一个开源的应用容器引擎,让开发者可以打包他们的应用以及依赖包到一个可移植的容器中,然后发布到任何流行的 Linu ...

  3. idea创建springboot工程,总出现响应超时问题,或者无法连接http://start.spring.io导致创建失败

    问题描述如下: idea创建springboot工程,总出现响应超时问题,或者无法连接http://start.spring.io导致创建失败 从我出现此类问题几次的解决方案 依照解决效率分为一下三种 ...

  4. Mysql数据导入导出功能(设置及使用)

    使用Mysql自带的outfile语法,将查询结果导成excel格式. 1.OUTFILE介绍及常见问题解决: )查询数据导出成csv 直接使用mysql导出csv方法 我们可以使用 into out ...

  5. JavaScript表达式和运算符 —— 基础语法(4)

    JavaScript基础语法(4) 运算符 运算符用于将一 个或者多个值变成结果值. 使用运算符的值称为操作数,运算符和操作数的组合称为表达式 JS中的运算符可以分成下面几类: 算术运算符 逻辑运算符 ...

  6. SK-learn实现k近邻算法【准确率随k值的变化】-------莺尾花种类预测

    代码详解: from sklearn.datasets import load_iris from sklearn.model_selection import train_test_split fr ...

  7. Junit借助Groboutils Core进行并发测试

    本文参考:http://www.voidcn.com/article/p-ybnvuffh-ke.html:转载请注明出处 junit是无法进行并发测试,但是又有需要并发测试的场景怎么办呢?此时可以借 ...

  8. 上传文件的input问题以及FormData特性

    1.input中除了type="file"还要加上name="file",否则$_FILES为空,input的name值就是为了区分每一个input的 2.va ...

  9. 通达OA-2017版本漏洞复现

    搭建环境 服务器 虚拟机系统版本:Windows Server 2016. 安装服务端 1.下载安装程序 这里我们下载的是2017版本的通达OA服务端: 2.安装程序 配置服务: 漏洞复现 1.任意文 ...

  10. 取 token 并查看 container 信息

    curl -i -k \ -H "Content-Type: application/json" \ -d ' { "auth": { "identi ...