一个序列,每个物品有三个权值 $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. css系列(4)简介

        本节用来简单介绍css.     (1)css: CSS 指层叠样式表 (Cascading Style Sheets): 功能以及作用:1.样式定义如何显示 HTML 元素; 2.样式通常存 ...

  2. 每天一个Linux命令(43)at命令

        at命令用于在指定时间执行命令.at允许使用一套相当复杂的指定时间的方法.可以用相对时间法指定,也可以用绝对时间法指定.     (1)用法:     用法:  at  [选项参数]  [时间 ...

  3. vuex的 例子

    最近在学习vuejs,一直有听说vuex,用来实现多组件共享的一种状态管理模式,但是网上都说,不要为了用vuex而用vuex,大概意思就是尽量少用vuex,一些小项目可以用bus来实现组件之间的传值问 ...

  4. 【leetcode刷提笔记】Search Insert Position

    Given a sorted array and a target value, return the index if the target is found. If not, return the ...

  5. Linux的XServer

    Moblin Core是在Gnome Mobile的平台上建立.我以前玩Linux,提交的都和图像没有关系,连Xwindows都不用启动,开机后直接进入文本命令行,所以这方面了解得很少,需要学习一下, ...

  6. 在IOS开发中,项目的目录结构如何搭建?

    网上有很多关于IOS开发的学习资料.然而却很少有关于设计一个项目时,如何设计其目录结构?这对于自学IOS的程序猿们,无疑有诸多不利.接下来,我就简单的谈下真正在公司中,项目的目录结构如何搭建: 以上为 ...

  7. linux下pycharm的使用

    百度搜索pycharm 然后打开pycharm的官网 然后在官网首页点击down   如果使用的是Linux系统,那么默认已经选择Linux版本 左边的down是全功能的IDE和WEB扩展,属于商业版 ...

  8. window7 共享wifi(不通过wifi软件)

    1.新建共享网络账号 管理员登录cmd输入:netsh wlan set hostednetwork mode=allow ssid=4Gtest key=12345678 ssid是无线网络名称.k ...

  9. javascript 时间日期处理相加相减

    var d = new Date("2008/04/15"); d.setMonth(d.getMonth() + 1 + 1);//加一个月,同理,可以加一天:getDate() ...

  10. SPOJ1825 FTOUR2 - Free tour II

    本文版权归ljh2000和博客园共有,欢迎转载,但须保留此声明,并给出原文链接,谢谢合作. 本文作者:ljh2000 作者博客:http://www.cnblogs.com/ljh2000-jump/ ...