Wannafly Winter Camp Day8(Div1,onsite) E题 Souls-like Game 线段树 矩阵乘法
(有任何问题欢迎留言或私聊 && 欢迎交流讨论哦
Catalog
@
Problem:传送门
Portal
原题目描述在最下面。
简单的说,每个点是一个矩阵,区间赋值和区间求积。
Solution:
\(div2\)版本就\(O(n*m*9)\)暴力更新暴力矩阵乘法求答案就行了,代码挺短的,有需要的话去另一篇博客里有代码。

\(div1\)题解就上面这个,相信大家看完应该都能\(ac\)。
本题只有两种操作,区间赋值和区间求和(矩阵的积)。很自然就想到要用线段树优化咯,然后线段树每个节点都是一个矩阵。
但是这题要先把区间长度扩展为2的幂次,为什么呢?因为:
长度为\(n\)的区间长度有大概\(log(n)\)种,但是当\(n\)不是\(2\)的幂次的时候,各种区间的长度是没有规律的。
这题线段树每个节点维护的是矩阵信息,用\(lazy\)标记优化区间赋值时,其实就是求矩阵的\(k\)次幂。
因为会有很多区间的长度相同,可以先把矩阵的k次幂预处理出来。
而只有当总长度是2的幂次时,每个节点覆盖的区间长度都会是2的幂次。这样就解释完了。
理解了这个,这题就随便写了。
AC_Code:
//哇,这题ac完感觉好爽啊
//第一次写这种结构体线段树还重载操作符的,海星
//没有人写博客,只能看着官方题解意会解法
#include<bits/stdc++.h>
#define clr(a, b) memset(a,b,sizeof((a)))
#define lson rt<<1
#define rson rt<<1|1
using namespace std;
typedef long long LL;
const int MXN = 2e5 + 7;
const LL mod = 998244353;
int n, m, Q;
int ar[MXN][3][3], two[33];
int lazy[MXN<<2][3][3], flag[MXN<<2];
map<int, int> mp;
struct edge {
int opt, l, r;
int ar[3][3];
}node[MXN];
struct lp {
int sum[3][3];
friend lp operator *(const lp&a, const lp&b) {
lp c;
clr(c.sum, 0);
for(int k = 0; k < 3; ++k) for(int i = 0; i < 3; ++i) for(int j = 0; j < 3; ++j) {
c.sum[i][j] = (c.sum[i][j]+(LL)a.sum[i][k]*b.sum[k][j])%mod;
}
return c;
}
}cw[MXN<<2], tp[MXN][33];
void push_up(int rt) {
cw[rt] = cw[lson] * cw[rson];
}
void build(int l,int r,int rt) {
flag[rt] = -1;
if(l == r) {
for(int i = 0; i < 3; ++i) for(int j = 0; j < 3; ++j) cw[rt].sum[i][j] = ar[l][i][j];
return ;
}
int mid = (l + r) >> 1;
build(l, mid, lson); build(mid+1,r,rson);
push_up(rt);
}
void push_down(int l,int mid,int r,int rt) {
if(flag[rt] == -1) return;
flag[lson] = flag[rson] = flag[rt];
for(int i = 0; i < 3; ++i) for(int j = 0; j < 3; ++j) lazy[lson][i][j] = lazy[rt][i][j], lazy[rson][i][j] = lazy[rt][i][j];
cw[lson] = tp[flag[rt]][mp[mid-l+1]-1];
cw[rson] = tp[flag[rt]][mp[r-mid]-1];
assert(mp[mid-l+1]); assert(mp[r-mid]);
flag[rt] = -1;
}
void update(int L,int R,int id,int l,int r,int rt) {
if(L <= l && r <= R) {
flag[rt] = id;
for(int i = 0; i < 3; ++i) for(int j = 0; j < 3; ++j) lazy[rt][i][j] = node[id].ar[i][j];
assert(mp[r-l+1]);
cw[rt] = tp[id][mp[r-l+1]-1];
return ;
}
int mid = (l + r) >> 1;
push_down(l, mid, r, rt);
if(L > mid) update(L, R, id, mid+1, r, rson);
else if(R <= mid) update(L, R, id, l, mid, lson);
else {
update(L,mid,id,l,mid,lson); update(mid+1,R,id,mid+1,r,rson);
}
push_up(rt);
}
lp query(int L,int R,int l,int r,int rt) {
if(L <= l && r <= R) {
return cw[rt];
}
int mid = (l + r) >> 1;
push_down(l, mid, r, rt);
if(L > mid) return query(L, R, mid+1, r, rson);
else if(R <= mid) return query(L, R, l, mid, lson);
else {
return query(L,mid,l,mid,lson)*query(mid+1,R,mid+1,r,rson);
}
}
int main() {
two[0] = 1, mp[1] = 1;
for(int i = 1; i <= 17; ++i) two[i] = two[i-1] << 1, mp[1<<i] = i + 1;
scanf("%d%d", &n, &Q);
for(int i = 1; i < n; ++i) {
for(int j = 0; j < 3; ++j) for(int k = 0; k < 3; ++k) scanf("%d", &ar[i][j][k]);
}
m = 2;
while(m < n) m <<= 1;
build(1, m, 1);
int opt, l, r;
for(int i = 1; i <= Q; ++i) {
scanf("%d%d%d", &node[i].opt, &node[i].l, &node[i].r);
if(node[i].opt == 1) {
for(int k = 0; k < 3; ++k) for(int j = 0; j < 3; ++j) {
scanf("%d", &node[i].ar[k][j]);
tp[i][0].sum[k][j] = node[i].ar[k][j];
}
for(int k = 1; k <= 17; ++k) {
tp[i][k] = tp[i][k-1] * tp[i][k-1];
}
update(node[i].l, node[i].r, i, 1, m, 1);
}else {
LL ans = 0;
lp a = query(node[i].l, node[i].r-1, 1, m, 1);
for(int i = 0; i < 3; ++i) for(int j = 0; j < 3; ++j) ans = (ans + a.sum[i][j]) % mod;
printf("%lld\n", ans);
}
}
return 0;
}
Problem Description:

Wannafly Winter Camp Day8(Div1,onsite) E题 Souls-like Game 线段树 矩阵乘法的更多相关文章
- CCPC-Wannafly Winter Camp Day8 (Div2, onsite) A 题 Aqours (精巧的树形DP)
题目链接: https://www.cometoj.com/contest/29/problem/A?problem_id=414 Aqours 题目描述 Aqours 正在 LoveLive! 决赛 ...
- CCPC-Wannafly Winter Camp Day8 (Div2, onsite) 补题
A Aqours 题解: https://www.cnblogs.com/qieqiemin/p/11251645.html D:吉良吉影的奇妙计划 (暴力打表) 题目描述 吉良吉影是一个平凡的上班族 ...
- Wannafly Winter Camp 2020 Day 5C Self-Adjusting Segment Tree - 区间dp,线段树
给定 \(m\) 个询问,每个询问是一个区间 \([l,r]\),你需要通过自由地设定每个节点的 \(mid\),设计一种"自适应线段树",使得在这个线段树上跑这 \(m\) 个区 ...
- Wannafly Winter Camp Day5 Div1 E题 Fast Kronecker Transform 转化为NTT或FFT
目录 Catalog Solution: (有任何问题欢迎留言或私聊 && 欢迎交流讨论哦 Catalog @ Problem:传送门 原题目描述在最下面. 对给定的式子算解. ...
- CCPC-Wannafly Winter Camp Day8 (Div2, onsite)
咕咕咕. camp补题. 传送门:https://www.zhixincode.com/contest/29/problems A.Aqours 题意:有一棵有根树,根节点为1,给出每个结点的父 ...
- MAZE(2019年牛客多校第二场E题+线段树+矩阵乘法)
题目链接 传送门 题意 在一张\(n\times m\)的矩阵里面,你每次可以往左右和下三个方向移动(不能回到上一次所在的格子),\(1\)表示这个位置是墙,\(0\)为空地. 现在有\(q\)次操作 ...
- 2019 wannafly winter camp day5-8代码库
目录 day5 5H div2 Nested Tree (树形dp) 5F div2 Kropki (状压dp) 5J div1 Special Judge (计算几何) 5I div1 Sortin ...
- Wannafly Winter Camp 2019.Day 8 div1 E.Souls-like Game(线段树 矩阵快速幂)
题目链接 \(998244353\)写成\(99824435\)然后调这个线段树模板1.5h= = 以后要注意常量啊啊啊 \(Description\) 每个位置有一个\(3\times3\)的矩阵, ...
- 2019 wannafly winter camp
2019 wannafly winter camp Name Rank Solved A B C D E F G H I J K day1 9 5/11 O O O O O day2 5 3/11 O ...
随机推荐
- SCP-Py-002
项目编号:Py-002 项目等级:EuclidKeter 特殊收容措施: Py-002-1目前被映射在Researcher Kevin的服务器位于Site-Pyproject地下防无线电渗透室且被切断 ...
- Maven进行自动构建
一个很常见的错误就是路径问题,要把jdk放到java工程的路径里,之前一直默认是jre https://blog.csdn.net/lslk9898/article/details/73836745 ...
- 网页head头部meta和link标签使用大全
<!-- 声明文档使用的字符编码 --> <meta charset="utf-8"> <!-- 声明文档的兼容模式 --> <meta ...
- ZROI week5
考试 Part 简单题,从结尾倒着扫一遍就行. Pref 选一个最长的好的序列. 题目有点小简单,似乎直接哈希就行,然后还打了一遍\(kmp\). Chess 一道很不错的题目,用异或维护修改即可. ...
- vue开发请求本地模拟数据的配置方法(转)
VUE开发请求本地数据的配置,早期的vue-lic下面有dev-server.js和dev-client.js两文件,请求本地数据在dev-server.js里配置,最新的vue-webpack-te ...
- PAT甲级——A1148 WerewolfSimpleVersion【20】
Werewolf(狼人杀) is a game in which the players are partitioned into two parties: the werewolves and th ...
- 【题解】An Easy Problem
题目描述 给定一个正整数N,求最小的.比N大的正整数M,使得M与N的二进制表示中有相同数目的1. 举个例子,假如给定的N为78,其二进制表示为1001110,包含4个1,那么最小的比N大的并且二进制表 ...
- tdom中selectNodes的使用
tdom中selectNodes的使用 */--> pre.src {background-color: #002b36; color: #839496;} pre.src {backgroun ...
- HDU 1261 字串数(排列组合)
字串数 Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others)Total Submiss ...
- GCD 与XOR
题目:UVA12716 题意: 问 gcd(i,j) = i ^ j 的对数(j <=i <= N ) N的范围为30000000,有10000组样例 分析: 有几个结论:(1)若 a ...