Transformation

Time Limit: 15000/8000 MS (Java/Others)    Memory Limit: 65535/65536 K (Java/Others)
Total Submission(s): 7144    Accepted Submission(s): 1811

Problem Description
Yuanfang is puzzled with the question below:
There are n integers, a1, a2, …, an. The initial values of them are 0. There are four kinds of operations.
Operation 1: Add c to each number between ax and ay inclusive. In other words, do transformation ak<---ak+c, k = x,x+1,…,y.
Operation 2: Multiply c to each number between ax and ay inclusive. In other words, do transformation ak<---ak×c, k = x,x+1,…,y.
Operation 3: Change the numbers between ax and ay to c, inclusive. In other words, do transformation ak<---c, k = x,x+1,…,y.
Operation 4: Get the sum of p power among the numbers between ax and ay inclusive. In other words, get the result of axp+ax+1p+…+ay p.
Yuanfang has no idea of how to do it. So he wants to ask you to help him.
 
Input
There 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.
 
Output
For 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
 
这题是好题  
太太太恶心了
简直爆炸  ,这题我写了N次
取模取模  
最后的query也要取模
找BUG找了好久找不到
这题最傻逼的做法是用3个lazy 和 3 个sum 
但是这里对于不同的lazy优先级不同 
而且还有取模操作,那样写下来及其的繁琐
我参考大佬博客 发现这题最优化的写法应该是
开一个线段树 维护区间里面相同的值
这样的话无论C多少都好求
        for (int i = 1 ; i <= c ; i++)
               ans = (ans * tree[rt].eq) % mod;
        return (ans * ((tree[rt].r - tree[rt].l + 1) % mod) % mod) % mod;
如果C是10用多个lazy维护代码量就直接爆炸了
这样的方法还有一个很好的优化
就是pushdown操作一直递归下去,直到到达底层
这样的话就有效的解决繁琐的优先级处理问题
这样处理优先级问题就很容易了
我菜爆了,用线段树维护区间相同的值 ,太强了
 
附送一个fuck函数
 
 #include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <queue>
#include <stack>
using namespace std;
typedef long long LL;
#define fuck(x) cout<<"["<<x<<"]";
#define rtl rt<<1
#define rtr rt<<1|1
const int maxn = 1e5 + ;
const int mod = 1e4 + ;
const int INF = 2e9 + ;
int n, m;
struct node {
int l, r, eq, add, mul;
int mid() {
return (l + r) >> ;
}
} tree[maxn << ];
void build(int l, int r, int rt) {
tree[rt].l = l, tree[rt].r = r;
tree[rt].add = , tree[rt].mul = , tree[rt].eq = -;
if (l == r) {
tree[rt].eq = ;
return ;
}
int m = (l + r) >> ;
build(l, m, rtl);
build(m + , r, rtr);
}
void pushdown(int rt) {
if (tree[rt].l == tree[rt].r) return ;
if (tree[rt].eq != -) {
tree[rtl].eq = tree[rtr].eq = tree[rt].eq;
tree[rtl].add = tree[rtr].add = ;
tree[rtl].mul = tree[rtr].mul = ;
tree[rt].eq = -;
return ;
}
if (tree[rt].mul != ) {
if (tree[rtl].eq != -) tree[rtl].eq = (tree[rtl].eq * tree[rt].mul) % mod;
else {
pushdown(rtl);
tree[rtl].mul = (tree[rtl].mul * tree[rt].mul) % mod;
}
if (tree[rtr].eq != -) tree[rtr].eq = (tree[rtr].eq * tree[rt].mul) % mod;
else {
pushdown(rtr);
tree[rtr].mul = (tree[rtr].mul * tree[rt].mul) % mod;
}
tree[rt].mul = ;
}
if (tree[rt].add) {
if (tree[rtl].eq != -) tree[rtl].eq = (tree[rtl].eq + tree[rt].add) % mod;
else {
pushdown(rtl);
tree[rtl].add = (tree[rtl].add + tree[rt].add) % mod;
}
if (tree[rtr].eq != -) tree[rtr].eq = (tree[rtr].eq + tree[rt].add) % mod;
else {
pushdown(rtr);
tree[rtr].add = (tree[rtr].add + tree[rt].add) % mod;
}
tree[rt].add = ;
}
} void update(int L, int R, int rt, int op, int c) {
if (L <= tree[rt].l && tree[rt].r <= R ) {
if (op == ) {
tree[rt].eq = c;
tree[rt].mul = ;
tree[rt].add = ;
return ;
}
if (tree[rt].eq != -) {
if (op == ) tree[rt].eq = (tree[rt].eq + c) % mod;
else tree[rt].eq = (tree[rt].eq * c) % mod;
} else {
pushdown(rt);
if (op == ) tree[rt].add = (tree[rt].add + c) % mod;
else tree[rt].mul = (tree[rt].mul * c) % mod;
}
return ;
}
pushdown(rt);
int m = tree[rt].mid();
if (L <= m) update(L, R, rtl, op, c);
if (R > m) update(L, R, rtr, op, c);
} int query(int L, int R, int rt, int c) {
if (L <= tree[rt].l && tree[rt].r <= R && tree[rt].eq != -) {
int ans = ;
for (int i = ; i <= c ; i++)
ans = (ans * tree[rt].eq) % mod;
return (ans * ((tree[rt].r - tree[rt].l + ) % mod) % mod) % mod;
}
pushdown(rt);
int m = tree[rt].mid();
if (R <= m) return query(L, R, rtl, c);
else if (L > m) return query(L, R, rtr, c);
else return query(L, m, rtl, c) + query(m + , R, rtr, c);
}
int main() {
while(scanf("%d%d", &n, &m) != EOF) {
if (n == && m == ) break;
build(, n, );
while(m--) {
int op, x, y, c;
scanf("%d%d%d%d", &op, &x, &y, &c);
if (op == ) printf("%d\n", query(x, y, , c)%mod);
else update(x, y, , op, c);
}
}
return ;
}
 

Transformation 线段树好题 好题 (独立写出来对线段树不容易)的更多相关文章

  1. 【BZOJ 3196】二逼平衡树 线段树套splay 模板题

    我写的是线段树套splay,网上很多人写的都是套treap,然而本蒟蒻并不会treap 奉上sth神犇的模板: //bzoj3196 二逼平衡树,支持修改某个点的值,查询区间第k小值,查询区间某个值排 ...

  2. 51nod 1593 公园晨跑 | ST表(线段树?)思维题

    51nod 1593 公园晨跑 有一只猴子,他生活在一个环形的公园里.有n棵树围绕着公园.第i棵树和第i+1棵树之间的距离是 di ,而第n棵树和第一棵树之间的距离是 dn .第i棵树的高度是 hi ...

  3. UESTC 1591 An easy problem A【线段树点更新裸题】

    An easy problem A Time Limit: 2000/1000MS (Java/Others)     Memory Limit: 65535/65535KB (Java/Others ...

  4. ●线段树的三个题(poj 3225,hdu 1542,hdu 1828)

    ●poj 3225 Help with Intervals(线段树区间问题) ○赘述题目 给出以下集合操作: 然后有初始的一个空集S,和以下题目给出的操作指令,并输入指令: 要求进行指令操作后,按格式 ...

  5. HDU 1166 敌兵布阵(线段树/树状数组模板题)

    敌兵布阵 Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others) Total Submi ...

  6. 【线段树I:母题】hdu 1166 敌兵布阵

    [线段树I:母题]hdu 1166 敌兵布阵 题目链接:hdu 1166 敌兵布阵 题目大意 C国的死对头A国这段时间正在进行军事演习,所以C国间谍头子Derek和他手下Tidy又開始忙乎了.A国在海 ...

  7. HDU 5029 Relief grain --树链剖分第一题

    题意:给一棵树,每次给两个节点间的所有节点发放第k种东西,问最后每个节点拿到的最多的东西是哪种. 解法:解决树的路径上的修改查询问题一般用到的是树链剖分+线段树,以前不会写,后来学了一下树链剖分,感觉 ...

  8. BZOJ 2243 染色 | 树链剖分模板题进阶版

    BZOJ 2243 染色 | 树链剖分模板题进阶版 这道题呢~就是个带区间修改的树链剖分~ 如何区间修改?跟树链剖分的区间询问一个道理,再加上线段树的区间修改就好了. 这道题要注意的是,无论是线段树上 ...

  9. 【树状数组 思维题】luoguP3616 富金森林公园

    树状数组.差分.前缀和.离散化 题目描述 博艾的富金森林公园里有一个长长的富金山脉,山脉是由一块块巨石并列构成的,编号从1到N.每一个巨石有一个海拔高度.而这个山脉又在一个盆地中,盆地里可能会积水,积 ...

随机推荐

  1. 【springmvc+mybatis项目实战】杰信商贸-3.需求分析与数据库建模

    开发步骤需求:生产厂家信息维护基础表FACTORY_C 1.业务需求:a)<需求说明书>     1)描述业务功能     生产厂家模块     功能:为在购销合同模块中的货物信息和附件信 ...

  2. 基础的表ADT -数据结构(C语言实现)

    读数据结构与算法分析 表的概述 形如A1,A2,A3... 操作合集 PrintList MakeEmpty Find Insert Delete 表的简单数组实现 分析: PrintList和Fin ...

  3. 腾讯云ubuntu安装使用MySQL

    安装步骤 ubuntu@VM---ubuntu:~$ sudo apt-get install mysql-server (密码: root/root) ubuntu@VM---ubuntu:~$ s ...

  4. 通过流的方式操作hadoop的API

    通过流的方式操作hadoop的API 功能: 可以直接用来操作hadoop的文件系统 可以用在mapreduce的outputformat中设置RecordWrite 参考: 概念理解 http:// ...

  5. Python入门(3)

    一.列表 列表是用来储存和处理多个数据的数据类型,我们可以像下面这样来创建一个列表: my_list = [1, 2, 3] 列表和数学中的集合很像,但是,列表中的数据是可以重复,并且他们是有序的,列 ...

  6. solidity 智能合约操作

    合约编译 #!/usr/bin/env python # coding: utf8 import json import os # Solc Compiler from functools impor ...

  7. Linux 静态和动态添加路由

    (一)静态添加 1/5 首先让我们查看当前机器的路由表,执行如下命令:route -n [root@vnode33 network-scripts]# route -n Kernel IP routi ...

  8. “Hello World!”团队——Alpha发布用户使用报告

    博客内容: 1.用户体验报告表 2.用户评论截图 3.总结 一.用户体验报告表 用户使用报告 用户序号 用户姓名(化名) 性别 用户职业 使用频次 用户评论 1 小董 女 文学在读硕士 5 1.游戏界 ...

  9. ZOJ 1711 H-Sum It Up

    https://vjudge.net/contest/67836#problem/H Given a specified total t and a list of n integers, find ...

  10. Innodb 中 RR 隔离级别能否防止幻读?

    问题引出 我之前的一篇博客 数据库并发不一致分析 有提到过事务隔离级别以及相应加锁方式.能够解决的并发问题. 标准情况下,在 RR(Repeatable Read) 隔离级别下能解决不可重复读(当行修 ...