THUSC 2017 大魔法师
一个序列,每个物品有三个权值 $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 大魔法师的更多相关文章
- THUSCH 2017 大魔法师(矩阵乘法+线段树)
题意 https://loj.ac/problem/2980 思路 区间修改考虑用线段树维护.由于一段区间的 \(A,B,C\) 可以表示成由原来的 \(A,B,C\) 乘上带上系数再加上某一个某个常 ...
- 「THUSCH 2017」大魔法师 解题报告
「THUSCH 2017」大魔法师 狗体面太长,帖链接了 思路,维护一个\(1\times 4\)的答案向量表示\(A,B,C,len\),最后一个表示线段树上区间长度,然后每次的操作都有一个转移矩阵 ...
- 「THUSCH 2017」大魔法师
Description 大魔法师小 L 制作了 \(n\) 个魔力水晶球,每个水晶球有水.火.土三个属性的能量值.小 L 把这 \(n\) 个水晶球在地上从前向后排成一行,然后开始今天的魔法表演. 我 ...
- LOJ 2980 「THUSCH 2017」大魔法师——线段树
题目:https://loj.ac/problem/2980 线段树维护矩阵. 然后是 30 分.似乎是被卡常了?…… #include<cstdio> #include<cstri ...
- THUSC 2017 游记
Day0 早上在家里整理东西. 下午坐飞机去北京.(怎么又去北京,上周刚去的北京) 一开始飞机爬升的时候太无聊就睡着了.醒了以后就开始吃东西.吐槽一句:厦航的飞机就是好啊.上面的点心也比上次海航的好吃 ...
- THUSC 2017 D1T2 杜老师
这是个非常有趣的数学题啦... 其实大概推一推式子就能得到一个信息,就是答案一定是$2$的整数次幂,并且其实答案就是$2^{R-L+1-sum}$,其中$sum$表示有多少个数不能用$L-i-1$的数 ...
- LOJ2980 THUSC2017大魔法师(线段树+矩阵乘法)
线段树每个节点维护(A,B,C,len)向量,操作即是将其乘上一个矩阵. #include<iostream> #include<cstdio> #include<cma ...
- [LOJ#2980][THUSCH2017]大魔法师(线段树+矩阵)
每个线段树维护一个行向量[A,B,C,len]分别是这个区间的A,B,C区间和与区间长度,转移显然. 以及此题卡常,稍微哪里写丑了就能100->45. #include<cstdio> ...
- [THUSC2017]大魔法师:线段树
分析 在线段树上用\(4 \times 4\)的矩阵打标记. 代码 #include <bits/stdc++.h> #define rin(i,a,b) for(register int ...
随机推荐
- linux练习命令
任务一:按要求完成以下操作1)显示日期格式2)在/tmp/下新建目录test ,并指定权限6643)显示环境变量path,但将/root加入到$PATH中4)用cat显示/etc/passwd,并打印 ...
- python多线程编程(3): 使用互斥锁同步线程
问题的提出 上一节的例子中,每个线程互相独立,相互之间没有任何关系.现在假设这样一个例子:有一个全局的计数num,每个线程获取这个全局的计数,根据num进行一些处理,然后将num加1.很容易写出这样的 ...
- $用python实现快速排序算法
本文主要介绍用python实现基本的快速排序算法,体会一下python的快排代码可以写得多么简洁. 1. 三言两语概括算法核心思想 先从待排序的数组中找出一个数作为基准数(取第一个数即可),然后将原来 ...
- TIJ读书笔记02-控制执行流程
TIJ读书笔记02-控制执行流程 TIJ读书笔记02-控制执行流程 if-else 迭代 无条件分支 switch语句 所有条件语句都是以条件表达式的真假来决定执行路径,也就是通过布尔测试结果来决 ...
- js 和 jquery 里面几个获取宽高的调查
罗列下 js 和 jquery 里面获取宽高的方法: obj.offsetWidth = $obj.outerWidth() // offsetWidth obj.clientWidth = obj ...
- 20145231 《Java程序设计》第一周学习总结
20145231 <Java程序设计>第一周学习总结 教材学习内容总结 Java三大平台Java SE,Java EE,Java ME.其中,Java SE是我们学习的基础. Java S ...
- QT应用程序设置图标
一.纯Qt 1.下载图标:app.ico 2.新建记事本,输入:IDI_ICON1 ICON DISCARDABLE"app.ico":改变名字为jude.rc 3.将两个文件放在 ...
- IDEA: 遇到问题Error during artifact deployment. See server log for details.详解
IDEA 的配置确实有些烦人,完整的配置我之前发过,现在有个著名的报错: Error during artifact deployment. See server log for details. 这 ...
- DATE_FORMAT() 函数用于以不同的格式显示日期/时间数据。
DATE_FORMAT(date,format) format参数的格式有 %a 缩写星期名 %b 缩写月名 %c 月,数值 %D 带有英文前缀的月中的天 %d 月的天,数值(00-31) %e 月的 ...
- uniqueidentifier in SQL becomes lower case in c#
https://stackoverflow.com/questions/16938151/uniqueidentifier-in-sql-becomes-lower-case-in-c-sharp ...