Wannafly Winter Camp 2019.Day 8 div1 E.Souls-like Game(线段树 矩阵快速幂)
\(998244353\)写成\(99824435\)然后调这个线段树模板1.5h= =
以后要注意常量啊啊啊
\(Description\)
每个位置有一个\(3\times3\)的矩阵,要求支持区间赋值和求区间乘积。
输出答案对\(998244353\)取模后的结果。
\(n,q\leq10^5\)。
\(Solution\)
裸的线段树+矩阵快速幂是\(O(3^3q\log^2n)\)的,因为维护区间乘的话,区间赋值为矩阵\(A\)的时候要赋值\(A^{r-l+1}\),带一个快速幂。
考虑怎么把那个快速幂去掉。发现对于长度为\(n\)的线段树的区间长度只有\(O(\log n)\)种,可以预处理出\(A\)的区间次幂,直接赋值。
不同区间的长度可能比较乱,但是把线段树长度补成\(2^k\),就很容易维护了。
复杂度\(O(3^3(n+q)\log n)\)。
写了这个题的代码纯属闲...
//439ms 46MB
#include <cstdio>
#include <cctype>
#include <algorithm>
#define mod 998244353
#define gc() getchar()
#define MAXIN 300000
//#define gc() (SS==TT&&(TT=(SS=IN)+fread(IN,1,MAXIN,stdin),SS==TT)?EOF:*SS++)
typedef long long LL;
const int N=(1<<17)+7,M=1e5+5,BIT=17;
int ref[N];
char IN[MAXIN],*SS=IN,*TT=IN;
inline int read();
struct Matrix
{
int a[3][3];
inline void Read()
{
for(int i=0; i<3; ++i)
for(int j=0; j<3; ++j) a[i][j]=read();
}
Matrix operator *(const Matrix &x)
{
Matrix res;
for(int i=0; i<3; ++i)
for(int j=0; j<3; ++j)
{
LL tmp=0;
for(int k=0; k<3; ++k) tmp+=1ll*a[i][k]*x.a[k][j]%mod;
res.a[i][j]=tmp%mod;
}
return res;
}
}A[N],pw[M][BIT+1];
struct Segment_Tree
{
#define ls rt<<1
#define rs rt<<1|1
#define lson l,m,ls
#define rson m+1,r,rs
#define S N<<2
int tag[S];
Matrix t[S];
#undef S
#define Upd(rt,id,l) t[rt]=pw[id][ref[l]], tag[rt]=id
#define Update(rt) t[rt]=t[ls]*t[rs]
inline void PushDown(int rt,int m)
{
Upd(ls,tag[rt],m>>1), Upd(rs,tag[rt],m>>1), tag[rt]=0;
}
void Build(int l,int r,int rt)
{
if(l==r) {t[rt]=A[l]; return;}
int m=l+r>>1; Build(lson), Build(rson), Update(rt);
}
void Modify(int l,int r,int rt,int L,int R,int id)
{
if(L<=l && r<=R) {Upd(rt,id,r-l+1); return;}
if(tag[rt]) PushDown(rt,r-l+1);
int m=l+r>>1;
if(L<=m) Modify(lson,L,R,id);
if(m<R) Modify(rson,L,R,id);
Update(rt);
}
Matrix Query(int l,int r,int rt,int L,int R)
{
if(L<=l && r<=R) return t[rt];
if(tag[rt]) PushDown(rt,r-l+1);
int m=l+r>>1;
if(L<=m)
if(m<R) return Query(lson,L,R)*Query(rson,L,R);
else return Query(lson,L,R);
return Query(rson,L,R);
}
}T;
inline int read()
{
int now=0;register char c=gc();
for(;!isdigit(c);c=gc());
for(;isdigit(c);now=now*10+c-48,c=gc());
return now;
}
int main()
{
#define S 1,lim,1
int n=read()-1,Q=read(),lim=1,bit=0;
for(int i=1; i<=n; ++i) A[i].Read();
while(lim<n) lim<<=1, ++bit;
for(int i=0; i<=bit; ++i) ref[1<<i]=i;
T.Build(S);
for(int t=0; Q--; )
switch(read())
{
case 1:
{
int l=read(),r=read(); pw[++t][0].Read();
for(int i=1; i<=bit; ++i) pw[t][i]=pw[t][i-1]*pw[t][i-1];
T.Modify(S,l,r,t); break;
}
case 2:
{
int l=read(),r=read();
Matrix res=T.Query(S,l,r-1); LL ans=0;
for(int i=0; i<3; ++i)
for(int j=0; j<3; ++j) ans+=res.a[i][j];
printf("%d\n",(int)(ans%mod)); break;
}
}
return 0;
}
Wannafly Winter Camp 2019.Day 8 div1 E.Souls-like Game(线段树 矩阵快速幂)的更多相关文章
- Wannafly Winter Camp 2019.Day 8 div1 I.岸边露伴的人生经验(FWT)
题目链接 \(Description\) 给定\(n\)个十维向量\(\overrightarrow{V_i}=x_1,x_2,...,x_{10}\).定义\(\overrightarrow{V}= ...
- Wannafly Winter Camp 2020 Day 5C Self-Adjusting Segment Tree - 区间dp,线段树
给定 \(m\) 个询问,每个询问是一个区间 \([l,r]\),你需要通过自由地设定每个节点的 \(mid\),设计一种"自适应线段树",使得在这个线段树上跑这 \(m\) 个区 ...
- 2019 牛客暑期多校 B generator 1 (矩阵快速幂+倍增)
题目:https://ac.nowcoder.com/acm/contest/885/B 题意:给你x0,x1,让你求出xn,递推式时xn=a*xn-1+b*xn-2 思路:这个n特别大,我自己没有摸 ...
- 2019牛客多校第五场B-generator 1(矩阵快速幂)
generator 1 题目传送门 解题思路 矩阵快速幂.只是平时的矩阵快速幂是二进制的,这题要用十进制的快速幂. 代码如下 #include <bits/stdc++.h> #defin ...
- 2019 wannafly winter camp day 3
2019 wannafly winter camp day 3 J 操作S等价于将S串取反,然后依次遍历取反后的串,每次加入新字符a,当前的串是T,那么这次操作之后的串就是TaT.这是第一次转化. 涉 ...
- 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 ...
- 2019 wannafly winter camp day5-8代码库
目录 day5 5H div2 Nested Tree (树形dp) 5F div2 Kropki (状压dp) 5J div1 Special Judge (计算几何) 5I div1 Sortin ...
- 2020 CCPC Wannafly Winter Camp Day1 C. 染色图
2020 CCPC Wannafly Winter Camp Day1 C. 染色图 定义一张无向图 G=⟨V,E⟩ 是 k 可染色的当且仅当存在函数 f:V↦{1,2,⋯,k} 满足对于 G 中的任 ...
- 牛客wannafly 挑战赛14 B 前缀查询(trie树上dfs序+线段树)
牛客wannafly 挑战赛14 B 前缀查询(trie树上dfs序+线段树) 链接:https://ac.nowcoder.com/acm/problem/15706 现在需要您来帮忙维护这个名册, ...
随机推荐
- 微信浏览器发送ajax请求执行多次解决方法
http://www.cnblogs.com/whatlonelytear/p/8934738.html
- hdu3635
/* 一开始第a个球在第a个城市 操作T a b,把第a个球所在城市的所有球移到b所在的城市 操作Q a 要求输出 第a个球在哪个城市 第a个球所在的城市有几个球 第a个球移动次数 */ #inclu ...
- bitset用法详解
参见此博客: https://www.cnblogs.com/magisk/p/8809922.html
- node.js 的热更新
1.安装 npm i supervisor -gd 2.运行 supervisor server.js //server.js 是你自己的服务的js文件
- babel-cli 的使用
1.安装babel-cli npm i babel-cli -D 2.实现npm的初始化 npm init -y 3.配置package.json { "name": " ...
- js 压缩上传的图片方法(默认上传的是file文件)
//压缩图片方法 function compressImg(file,callback){ var src; var fileSize = parseFloat(parseInt(file['size ...
- 【转】flannel网络的VXLAN及host-gw
http://www.fly63.com/article/detial/1738 VXLAN是Linux内核本身支持的一种网络虚拟化技术,是内核的一个模块,在内核态实现封装解封装,构建出覆盖网络,其实 ...
- Centos6安装SaltStack
rpm -ivh https://mirrors.tuna.tsinghua.edu.cn/epel/6/x86_64/epel-release-6-8.noarch.rpm yum install ...
- CDOJ 1960 构造哈密顿路径
题意: 给定n个点的有向完全图,希望通过其中n-1条边将n个点串起来(2<=n<=1000) 欧拉路径:经过所有边且只经过一次 哈密顿路径:经过所有点且只经过一次 思路: 本题条件特殊,有 ...
- 【BZOJ1778】[Usaco2010 Hol]Dotp 驱逐猪猡
题解: 网上有一种复杂的方法..好像复杂度并没有优势就没看 定义f[i]表示i的期望经过次数,f[i]=sigma{f[j]*p/q/du[j]}+(i==1); 然后高斯消元就可以了 最后求出来的f ...