题目链接

\(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(线段树 矩阵快速幂)的更多相关文章

  1. Wannafly Winter Camp 2019.Day 8 div1 I.岸边露伴的人生经验(FWT)

    题目链接 \(Description\) 给定\(n\)个十维向量\(\overrightarrow{V_i}=x_1,x_2,...,x_{10}\).定义\(\overrightarrow{V}= ...

  2. Wannafly Winter Camp 2020 Day 5C Self-Adjusting Segment Tree - 区间dp,线段树

    给定 \(m\) 个询问,每个询问是一个区间 \([l,r]\),你需要通过自由地设定每个节点的 \(mid\),设计一种"自适应线段树",使得在这个线段树上跑这 \(m\) 个区 ...

  3. 2019 牛客暑期多校 B generator 1 (矩阵快速幂+倍增)

    题目:https://ac.nowcoder.com/acm/contest/885/B 题意:给你x0,x1,让你求出xn,递推式时xn=a*xn-1+b*xn-2 思路:这个n特别大,我自己没有摸 ...

  4. 2019牛客多校第五场B-generator 1(矩阵快速幂)

    generator 1 题目传送门 解题思路 矩阵快速幂.只是平时的矩阵快速幂是二进制的,这题要用十进制的快速幂. 代码如下 #include <bits/stdc++.h> #defin ...

  5. 2019 wannafly winter camp day 3

    2019 wannafly winter camp day 3 J 操作S等价于将S串取反,然后依次遍历取反后的串,每次加入新字符a,当前的串是T,那么这次操作之后的串就是TaT.这是第一次转化. 涉 ...

  6. 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 ...

  7. 2019 wannafly winter camp day5-8代码库

    目录 day5 5H div2 Nested Tree (树形dp) 5F div2 Kropki (状压dp) 5J div1 Special Judge (计算几何) 5I div1 Sortin ...

  8. 2020 CCPC Wannafly Winter Camp Day1 C. 染色图

    2020 CCPC Wannafly Winter Camp Day1 C. 染色图 定义一张无向图 G=⟨V,E⟩ 是 k 可染色的当且仅当存在函数 f:V↦{1,2,⋯,k} 满足对于 G 中的任 ...

  9. 牛客wannafly 挑战赛14 B 前缀查询(trie树上dfs序+线段树)

    牛客wannafly 挑战赛14 B 前缀查询(trie树上dfs序+线段树) 链接:https://ac.nowcoder.com/acm/problem/15706 现在需要您来帮忙维护这个名册, ...

随机推荐

  1. Laravel5使用QQ邮箱发送邮件配置

    在.env文件中设置如下MAIL_DRIVER=smtpMAIL_HOST=smtp.qq.comMAIL_PORT=465MAIL_USERNAME=00000000000@qq.comMAIL_P ...

  2. java子类对象和成员变量的隐写&方法重写

    1.子类继承的方法只能操作子类继承和隐藏的成员变量名字类新定义的方法可以操作子类继承和子类新生命的成员变量,但是无法操作子类隐藏的成员变量(需要适用super关键字操作子类隐藏的成员变量.) publ ...

  3. jenkins 回滚发布

    #jenkins拉取文件路径 workspace=/data/wos/testtemp #备份路径 backspace=/data/wos/back #不能提Git的文件 config=/data/w ...

  4. windows 下命令行启动停止mysql

    MySQL比较好玩一点就是它可以用多种方式启动,当然它也可以用多种方式关闭.下面我就mysql的几种启动方式简单的谈一谈,希望可以给大家提供一些参考. 第一种,用mysqld-nt来启动. 在没有进行 ...

  5. angular-cli ng build 打包完成后 打开文件显示空白

    将index.html 里面的<base href="/"> 改为<base href="./"> 前面加一个 点 就好了,然后再次打包 ...

  6. 眼底血管分割训练函数(SVM,Adaboost)

    # -*- coding: utf-8 -*- import numpy as np from sklearn import svm from sklearn.model_selection impo ...

  7. Lua中assert( )函数的使用

    当Lua遇到不期望的情况时就会抛出错误,比如:两个非数字进行相加:调用一个非函数的变量:访问表中不存在的值等.你也可以通过调用error函数显示的抛出错误,error的参数是要抛出的错误信息. ass ...

  8. mysql如何添加一个表的外键

    1:创建一个父表,主键作为子表的外键: create table province( pId int primary key auto_increment, pName varchar() ); 2: ...

  9. [转] babel的使用

    一.配置文件.babelrc .babelrc 文件存放在项目的根目录下. { "presets": [], "plugins": [] } presets 字 ...

  10. 期货大赛项目|三,autofac简单用法

    autofac是依赖注入 我们以前要引入一个dal层,是这么写的 private IDal _dao = new Dal() 我们可以看得出,这样写,我们的bll层不光依赖了接口IDal,还依赖了Da ...