一个序列,每个物品有三个权值 $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. loadrunder之脚本篇——action分类

    Action分类 l . Vuser_init 2. Vuser_end 3.  Action 在lr中用户的初始化操作应该存放在Vuser_init中.用户的结束操作存放在Vuser_end中.因为 ...

  2. Ajax+Spring MVC实现跨域请求(JSONP)

    背景: AJAX向后台(springmvc)发送请求,报错:已阻止交叉源请求:同源策略不允许读取 http://127.0.0.1:8080/DevInfoWeb/getJsonp 上的远程资源.可 ...

  3. json学习笔记--在JavaScript中的使用

    1.字符串转换为JavaScript对象 var jsonStr = '[' + '{"name":"陶国荣","sex":"男& ...

  4. Linux基本命令 关机命令

    linux下常用的关机命令有:shutdown.halt.poweroff.init:重启命令有:reboot.下面本文就主要介绍一些常用的关机命令以及各种关机命令之间的区别和具体用法. 首先来看一下 ...

  5. mongodb简介和特性

    1.mongodb是基于文档的(BSON,类似json的键值对来存储),不是基于表格,易于水平扩展,将内部相关的数据放在一起能提高数据库的操作性能.如果你想新建一个新的文档类型,不用事先告诉数据库关于 ...

  6. 建议37:按需选择sort或sorted

    # -*- coding:utf-8 -*- ''' 用法: sorted(iterable[, cmp[, key[, reverse]]]) s.sort([cmp[, key[, reverse ...

  7. ACM训练小结-2018年6月15日

    今天题目情况如下:A题:给出若干条边的边长,问这些边按顺序能否组成一个凸多边形,并求出这个多边形的最小包含圆.答题情况:无思路.正解(某种):第一问很简单.对第二问,如果R大于可行的最小R,那么按照放 ...

  8. linux 虚拟机在线添加新磁盘

    在线添加磁盘,扩展LVM卷案例   一.添加硬盘,在线扫描出来 首先到虚拟机那里添加一块硬盘,注意必须是SCSI类型的硬盘. 扫描硬盘,不用重启操作系统的. echo "- - -" ...

  9. Response对象介绍(服务器到客户端)

    1.response的状态码和响应头设置 package com.test; import java.io.IOException; import java.io.PrintWriter; impor ...

  10. 算法总结之 数组的partition调整

    给定一个有序数组arr, 调整arr使得这个数组的左半部分没有重复元素且升序,而且不用保证右边是否有序 分区就ok了 u区是 无重复且升序的  u是这个区域的最后位置,初始u=0 i做从左到右的遍历, ...