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 现在需要您来帮忙维护这个名册, ...
 
随机推荐
- XSS-HTML&javaSkcript&CSS&jQuery&ajax-CSS
			
CSS 1.表单的处理 <style> table, td, th{ border:1px; solid green;} th{ background-color:green; color ...
 - bzoj 1222
			
比较简单的背包dp,设计状态f[i][j]表示到了前i个物品,第一台机器加工时间为j,第二台机器加工所用的最小时间,然后背包转移即可 本题卡空间,需要滚动数组优化 本题卡时间,稍微卡下常就行 #inc ...
 - 论文阅读笔记三十七:Grid R-CNN(CVPR2018)
			
论文源址:https://arxiv.org/abs/1811.12030 开源代码:未公开 摘要 本文提出了目标检测网络Grid R-CNN,其基于网格定位机制实现准确的目标检测.传统方法主要基于回 ...
 - Java+selenium之WebDriver页面元素的操作(三)
			
1. 输入框(text field or textarea) WebElement we = driver.findElement(By.id("id")); //将输入框清空 w ...
 - UEditor上传自定义文件夹
			
需求:使用UEditor上传时需要知道具体到哪个章节得图片,所以得根据Session中得文件重新定义 修改Handler类: public HttpSessionState Session {get; ...
 - 使用layer弹出Ueditor实现父子传值
			
Layear的代码: function tankuang() { layer.open({ type: 2, title: false ...
 - Git 分支 - 分支的新建与合并
			
转载自:https://git-scm.com/book/zh/v1/Git-%E5%88%86%E6%94%AF-%E5%88%86%E6%94%AF%E7%9A%84%E6%96%B0%E5%BB ...
 - python的学习和使用
			
1.python的官网:https://www.python.org/ Python简介: .Python 是一个高层次的结合了解释性.编译性.互动性和面向对象的脚本语言. .Python 的设计具有 ...
 - ASP.NET Core IHostEnvironment和IApplicationLifetime介绍
			
IHostEnvironment获取程序信息 public void Configure(IApplicationBuilder app, IHostingEnvironment env) { app ...
 - Visual Studio 2015 插件开发入门
			
(1)安装 Visual Studio 2015 的时候选择 Visual Studio 扩展性工具(Visual Studio Extensibility Tools).对于已经安装好 Visual ...