一个序列,每个物品有三个权值 $A,B,C$

要求维护:

1.区间 $A_i+=B_i$

2.区间 $B_i+=C_i$

3.区间 $C_i+=A_i$

4.区间 $A_i+=v$

5.区间 $B_i \times = v$

6.区间 $C_i = v$

7.询问区间 $A,B,C$ 各自的和

线段树,每个点维护 $A,B,C,区间长度$

每次修改相当于区间乘一个转移矩阵

时间复杂度 $O(16nlogn)$

垫底

#include <bits/stdc++.h>
#define LL long long
using namespace std;
#define rep(i, s, t) for (register int i = (s), i##end = (t); i <= i##end; ++i)
#define dwn(i, s, t) for (register int i = (s), i##end = (t); i >= i##end; --i)
inline int read() {
int x = , f = ; char ch = getchar();
for (; !isdigit(ch); ch = getchar())if (ch == '-')f = -f;
for (; isdigit(ch); ch = getchar()) x = * x + ch - '';
return x * f;
}
const int mod = , maxn = 2.5e5 + ;
#define ls (x << 1)
#define rs ((x << 1) | 1)
int n, q, A[maxn], B[maxn], C[maxn];
struct Matrix {
int a[][];
Matrix() {memset(a, , sizeof(a));}
Matrix operator * (const Matrix &b) const {
Matrix c;
rep(i, , ) rep(j, , ) rep(k, , )
(c.a[i][j] += (1LL * a[i][k] * b.a[k][j] % mod)) %= mod;
return c;
}
Matrix operator + (const Matrix &b) const {
Matrix c;
rep(i, , ) rep(j, , ) c.a[i][j] = (a[i][j] + b.a[i][j]) % mod;
return c;
}
}tag[maxn << ];
int seg[maxn << ][];
void mul(int *f, Matrix gg) {
int tmp[] = {, , , };
rep(i, , ) rep(j, , ) (tmp[j] += (1LL * f[i] * gg.a[i][j] % mod)) %= mod;
rep(i, , ) f[i] = tmp[i];
}
inline int clear(Matrix x) {
if (!(x.a[][] == && x.a[][] == && x.a[][] == && x.a[][] == ))return false;
if (x.a[][] || x.a[][] || x.a[][] || x.a[][] || x.a[][] || x.a[][])return false;
if (x.a[][] || x.a[][] || x.a[][] || x.a[][] || x.a[][] || x.a[][]) return false;
return true;
}
inline void pushup(int x) {
rep(i, , ) seg[x][i] = (seg[ls][i] + seg[rs][i]) % mod;
}
inline void pushdown(int x) {
if(clear(tag[x])) return;
tag[ls] = tag[ls] * tag[x], tag[rs] = tag[rs] * tag[x];
mul(seg[ls], tag[x]), mul(seg[rs], tag[x]);
rep(i, , ) rep(j, , ) tag[x].a[i][j] = (i == j);
}
inline void build(int x, int l, int r) {
if(l == r) {
seg[x][] = A[l]; seg[x][] = B[l]; seg[x][] = C[l]; seg[x][] = ;
return;
}
int mid = (l + r) >> ;
build(ls, l, mid); build(rs, mid + , r);
pushup(x);
}
Matrix cur; int res[];
inline void update(int x, int l, int r, int L, int R) {
if(L <= l && r <= R) {
mul(seg[x], cur);
tag[x] = tag[x] * cur;
return;
}
pushdown(x);
int mid = (l + r) >> ;
if(L <= mid) update(ls, l, mid, L, R);
if(R > mid) update(rs, mid + , r, L, R);
pushup(x);
}
inline void query(int x, int l, int r, int L, int R) {
if(L <= l && r <= R) {
rep(i, , ) (res[i] += seg[x][i]) %= mod;
return;
}
pushdown(x);
int mid = (l + r) >> ;
if(L <= mid) query(ls, l, mid, L, R);
if(R > mid) query(rs, mid + , r, L, R);
}
int main() {
n = read();
rep(i, , (n<<)) rep(j, , ) rep(k, , ) tag[i].a[j][k] = (j == k);
rep(i, , n) A[i] = read(), B[i] = read(), C[i] = read();
build(, , n);
q = read();
while(q--) {
int opt = read(), l = read(), r = read();
rep(i, , ) rep(j, , ) cur.a[i][j] = (i == j);
if(opt == ) cur.a[][]++;
else if(opt == ) cur.a[][]++;
else if(opt == ) cur.a[][]++;
else if(opt == ) (cur.a[][] += read()) %= mod;
else if(opt == ) cur.a[][] = read();
else if(opt == ) cur.a[][] = , cur.a[][] = read();
if(opt != ) update(, , n, l, r);
if(opt == ) {
rep(i, , ) res[i] = ;
query(, , n, l, r);
printf("%d %d %d\n", res[], res[], res[]);
continue;
}
}
}

THUSC 2017 大魔法师的更多相关文章

  1. THUSCH 2017 大魔法师(矩阵乘法+线段树)

    题意 https://loj.ac/problem/2980 思路 区间修改考虑用线段树维护.由于一段区间的 \(A,B,C\) 可以表示成由原来的 \(A,B,C\) 乘上带上系数再加上某一个某个常 ...

  2. 「THUSCH 2017」大魔法师 解题报告

    「THUSCH 2017」大魔法师 狗体面太长,帖链接了 思路,维护一个\(1\times 4\)的答案向量表示\(A,B,C,len\),最后一个表示线段树上区间长度,然后每次的操作都有一个转移矩阵 ...

  3. 「THUSCH 2017」大魔法师

    Description 大魔法师小 L 制作了 \(n\) 个魔力水晶球,每个水晶球有水.火.土三个属性的能量值.小 L 把这 \(n\) 个水晶球在地上从前向后排成一行,然后开始今天的魔法表演. 我 ...

  4. LOJ 2980 「THUSCH 2017」大魔法师——线段树

    题目:https://loj.ac/problem/2980 线段树维护矩阵. 然后是 30 分.似乎是被卡常了?…… #include<cstdio> #include<cstri ...

  5. THUSC 2017 游记

    Day0 早上在家里整理东西. 下午坐飞机去北京.(怎么又去北京,上周刚去的北京) 一开始飞机爬升的时候太无聊就睡着了.醒了以后就开始吃东西.吐槽一句:厦航的飞机就是好啊.上面的点心也比上次海航的好吃 ...

  6. THUSC 2017 D1T2 杜老师

    这是个非常有趣的数学题啦... 其实大概推一推式子就能得到一个信息,就是答案一定是$2$的整数次幂,并且其实答案就是$2^{R-L+1-sum}$,其中$sum$表示有多少个数不能用$L-i-1$的数 ...

  7. LOJ2980 THUSC2017大魔法师(线段树+矩阵乘法)

    线段树每个节点维护(A,B,C,len)向量,操作即是将其乘上一个矩阵. #include<iostream> #include<cstdio> #include<cma ...

  8. [LOJ#2980][THUSCH2017]大魔法师(线段树+矩阵)

    每个线段树维护一个行向量[A,B,C,len]分别是这个区间的A,B,C区间和与区间长度,转移显然. 以及此题卡常,稍微哪里写丑了就能100->45. #include<cstdio> ...

  9. [THUSC2017]大魔法师:线段树

    分析 在线段树上用\(4 \times 4\)的矩阵打标记. 代码 #include <bits/stdc++.h> #define rin(i,a,b) for(register int ...

随机推荐

  1. set去重,session,cookie c#与python 对比

    端口,发送请求进行监听,然后处理 session 是存储在服务器端的数据,靠sessionId来验证获取信息,没有大小和类型限制, cookie   是存储在客户端的数据,可以长期使用,有面临被获取的 ...

  2. OpenGL学习进程(3)第一课:初始化窗体

        本节是OpenGL学习的第一个课时,下面介绍如何初始化一个窗体:     (1)显示一个有蓝色背景的窗体: #include <GL/glut.h> #include <st ...

  3. IMX6Q RTC驱动分析

    对于在工作中学习驱动的,讲究的是先使用,再理解.好吧,我们来看看板子里是如何注册的? 在板文件里,它的注册函数是这样的: imx6q_add_imx_snvs_rtc() 好吧,让我们追踪下去: 1 ...

  4. Struts2笔记02——Struts2 概述(转)

    原始内容:https://www.tutorialspoint.com/struts_2/basic_mvc_architecture.htm Struts2是基于MVC设计模式的一种流行.成熟的We ...

  5. MySQL索引操作命令详解

    创建索引: MySql创建索引的语法如下: CREATE [UNIQUE|FULLTEXT|SPATIAL] INDEX index_name [USING index_type] ON table_ ...

  6. Windows 2012 系统汉化

    远程登录服务器 控制面板,选择“语言” (Windows 2012 自带的语言包 ) 此处需要等待 安装完成,选择中文 重启后 应该就不需要做其他的操作了

  7. HMM简单理解(来自quora&其他网上资料)

    转载自quora: 连接:https://www.quora.com/What-is-a-simple-explanation-of-the-Hidden-Markov-Model-algorithm ...

  8. 从Shell眼中看世界【TLCL】

    字符展开: echo * 路径名展开: echo D* 隐藏文件路径名展开   ls -d .[!.]?* 波浪线展开: echo ~ 算术表达式展开: $((expression)) 花括号展开: ...

  9. json01-json简介和语法

    JSON: JavaScript Object Notation(JavaScript 对象表示法) JSON 是存储和交换文本信息的语法.类似 XML,但比 XML 更小.更快,更易解析,是轻量级的 ...

  10. Windows 安装Mysql8.0 绿色包

    〇.准备: MySQL8.0 Windows zip包下载地址:https://cdn.mysql.com//Downloads/MySQL-8.0/mysql-8.0.11-winx64.zip 环 ...