[HDU6155]Subsequence Count(线段树+矩阵)
DP式很容易得到,发现是线性递推形式,于是可以矩阵加速。又由于是区间形式,所以用线段树维护。
https://www.cnblogs.com/Miracevin/p/9124511.html
关键在于证明区间操作中,可以直接在打标记的位置翻转矩阵两行两列。
上面网址用代数形式证了一遍,这里考虑从矩阵本身解释。
由线代内容可知,将一个矩阵作初等行变换,相当于将其左乘一个作了相应初等列变换的单位矩阵。同理将一个矩阵作初等列变换,相当于将其又乘一个作了相应初等行变换的单位矩阵。
这里,左乘的矩阵$T=\begin{bmatrix}0 & 1 & 0 \\ 1 & 0 & 0 \\ 0 & 0 & 1\end{bmatrix}$,右乘的矩阵$T'$同样也是这个。
我们发现,$T\times T'$就是单位矩阵,也就是说$T$的逆矩阵就是自己。
于是有,$T\times A\times T'\times T\times B\times T'=T\times A\times B\times T'$。
这就说明中间的所有矩乘操作都可以被省略,只留下首尾的$T$和$T'$。
这也就证明了,对区间矩阵积直接做变换是正确的。
#include<cstdio>
#include<cstring>
#include<algorithm>
#define ls (x<<1)
#define rs (ls|1)
#define lson ls,L,mid
#define rson rs,mid+1,R
#define rep(i,l,r) for (int i=(l); i<=(r); i++)
using namespace std; const int N=,mod=1e9+;
bool tag[N<<];
int n,Q,T,op,l,r; struct Mat{ int a[][]; }v[N<<];
const Mat D[]={(Mat){,,,,,,,,},(Mat){,,,,,,,,}};
int calc(Mat a){ return (a.a[][]+a.a[][])%mod; } Mat operator *(const Mat &a,const Mat &b){
Mat c; memset(c.a,,sizeof(c.a));
rep(i,,) rep(j,,) rep(k,,)
c.a[i][k]=(c.a[i][k]+1ll*a.a[i][j]*b.a[j][k])%mod;
return c;
} void put(int x){
tag[x]^=;
swap(v[x].a[][],v[x].a[][]);
swap(v[x].a[][],v[x].a[][]);
swap(v[x].a[][],v[x].a[][]);
swap(v[x].a[][],v[x].a[][]);
swap(v[x].a[][],v[x].a[][]);
swap(v[x].a[][],v[x].a[][]);
} void push(int x){ if (tag[x]) put(ls),put(rs),tag[x]=; } void build(int x,int L,int R){
tag[x]=;
if (L==R){ char t; scanf(" %c",&t); v[x]=D[t-'']; return; }
int mid=(L+R)>>; build(lson); build(rson); v[x]=v[ls]*v[rs];
} void mdf(int x,int L,int R,int l,int r){
if (L==l && r==R){ put(x); return; }
int mid=(L+R)>>; push(x);
if (r<=mid) mdf(lson,l,r);
else if (l>mid) mdf(rson,l,r);
else mdf(lson,l,mid),mdf(rson,mid+,r);
v[x]=v[ls]*v[rs];
} Mat que(int x,int L,int R,int l,int r){
if (L==l && r==R) return v[x];
int mid=(L+R)>>; push(x);
if (r<=mid) return que(lson,l,r);
else if (l>mid) return que(rson,l,r);
else return que(lson,l,mid)*que(rson,mid+,r);
} int main(){
freopen("hdu6155.in","r",stdin);
freopen("hdu6155.out","w",stdout);
for (scanf("%d",&T); T--; ){
scanf("%d%d",&n,&Q); build(,,n);
while (Q--){
scanf("%d%d%d",&op,&l,&r);
if (op==) mdf(,,n,l,r); else printf("%d\n",calc(que(,,n,l,r)));
}
}
return ;
}
[HDU6155]Subsequence Count(线段树+矩阵)的更多相关文章
- HDU.6155.Subsequence Count(线段树 矩阵)
题目链接 首先考虑询问[1,n]怎么做 设 f[i][0/1]表示[1,i]以0/1结尾的不同子序列个数 则 \(if(A[i]) f[i][1] = f[i-1][0] + f[i-1][1] + ...
- HDU 6155 Subsequence Count 线段树维护矩阵
Subsequence Count Time Limit: 10000/5000 MS (Java/Others) Memory Limit: 256000/256000 K (Java/Oth ...
- Wannafly Winter Camp 2019.Day 8 div1 E.Souls-like Game(线段树 矩阵快速幂)
题目链接 \(998244353\)写成\(99824435\)然后调这个线段树模板1.5h= = 以后要注意常量啊啊啊 \(Description\) 每个位置有一个\(3\times3\)的矩阵, ...
- Codeforces 750E - New Year and Old Subsequence(线段树维护矩阵乘法,板子题)
Codeforces 题目传送门 & 洛谷题目传送门 u1s1 我做这道 *2600 的动力是 wjz 出了道这个套路的题,而我连起码的思路都没有,wtcl/kk 首先考虑怎样对某个固定的串计 ...
- CF719E(线段树+矩阵快速幂)
题意:给你一个数列a,a[i]表示斐波那契数列的下标为a[i],求区间对应斐波那契数列数字的和,还要求能够维护对区间内所有下标加d的操作 分析:线段树 线段树的每个节点表示(f[i],f[i-1])这 ...
- 【Codeforces718C】Sasha and Array 线段树 + 矩阵乘法
C. Sasha and Array time limit per test:5 seconds memory limit per test:256 megabytes input:standard ...
- Codeforces Round #337 (Div. 2) D. Vika and Segments 线段树 矩阵面积并
D. Vika and Segments Vika has an infinite sheet of squared paper. Initially all squares are whit ...
- 线段树 + 矩阵 --- ZOJ 3772 Calculate the Function
Calculate the Function Problem's Link: http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemCod ...
- FZU 2105 Digits Count(线段树)
Problem 2105 Digits Count Accept: 302 Submit: 1477 Time Limit: 10000 mSec Memory Limit : 262144 KB P ...
随机推荐
- 【译】第十二篇 Integration Services:高级日志记录
本篇文章是Integration Services系列的第十二篇,详细内容请参考原文. 简介在前一篇文章我们配置了SSIS内置日志记录,演示了简单和高级日志配置,保存并查看日志配置,生成自定义日志消息 ...
- align-items和align-content的区别
最近在研究flex布局,容器中有两个属性,是用来定义crossAxis测轴排列方式的.一开始接触align-items还可以理解感觉不难,后来看到align-content就感觉有点混淆了,特开一篇博 ...
- 【矩阵】RQ/QR 分解
Multiple View Geometry in Computer Vision A.4.1.1 (page 579) 将一个 3x3 矩阵 $ A $ 进行 RQ 分解是将其分解成为一个上三角阵 ...
- PCA主成分分析理解
一.理论概述 1)问题引出 先看如下几张图: 从上述图中可以看出,如果将3个图的数据点投影到x1轴上,图1的数据离散度最高,图3其次,图2最小.数据离散性越大,代表数据在所投影的维度上具有越高的区分度 ...
- Shell中三种引号的用法及区别
Linux Shell中有三种引号,分别为双引号(" ").单引号(' ')以及反引号(` `). 其中双引号对字符串中出现的$.''.`和\进行替换:单引号不进行替换,将字符串中 ...
- Flask:使用Eclipse+PyDev插件编辑基于package的项目
Windows 10家庭中文版,Python 3.6.4,Flask 1.0.2,Eclipse Oxygen.1a Release (4.7.1a),PyDev 6.3.2 本文记录了 使用Ecli ...
- 写在用Mac进行Java开发之前
在用Mac进行开发之前,建议浏览以下几个概念. 1. 几个基础概念 - 计算机 计算机(computer)俗称电脑,发明者是约翰·冯·诺依曼,计算机是现代一种用于高速计算的电子计算机器,可以进行数值计 ...
- 题解 P1074 【靶形数独 】
这是一神题!!! 可能是因为我太弱了,题解都看不太懂QWQ 不过感谢wng老师的提醒,我写出了这个样的的代码. 分析: 这道题是一个搜索(dfs).很神奇很暴力的题 首先,你需要看懂题目.(可以先去玩 ...
- dedecms调用文章列表第一篇和下面几篇不同的方法
{dede:arclist row=1 orderby=pubdate infolen=60 limit=0,1} <li class="dot1"><img s ...
- Spring 事务管理基础知识点
参考文章 spring事物配置,声明式事务管理和基于@Transactional注解的使用 尚硅谷 佟刚 Spring视频教程PPT Spring支持编程式事务管理和声明式事务管理两种方式 编程式事务 ...