[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 ...
随机推荐
- Eureka简介
Eureka是Spring Cloud Netfix 的一个子模块,也是核心模块之一,用于云端服务发现.一个基于RestFul的服务,用于定位服务,以实现云端中间层服务发现和中间层转移. 服务注册与发 ...
- QByteArray储存二进制数据(包括结构体,自定义QT对象)
因为利用QByteArray可以很方便的利用其API对内存数据进行访问和修改, 构建数据库blob字段时必不可少; 那如何向blob内写入自定义的结构体和类 //自定义person结构体 typede ...
- Python——杂记
python 最近出错总结: 1.而for..in ..中不要用else if x in y: print else: print2.def fibs(num): ... ...
- MySQL5.7之多源复制&Nginx中间件(下)【转】
有生之年系列----MySQL5.7之多源复制&Nginx中间件(下)-wangwenan6-ITPUB博客http://blog.itpub.net/29510932/viewspace-1 ...
- The data protection operation was unsuccessful. This may have been caused by not having the user profile loaded for the current thread's user context,
在iis7.0布署网站后运行的错误,大致意思是:数据保护操作是不成功的.这可能是由于没有为当前线程的用户加载用户配置文件的导致 解决办法: 先为自己的网站新建一个应用程序池,然后新建的应用程序池上右键 ...
- Java--Jackson转换Date,Timestamp 到格式化字符串
package com.diandaxia.test; import java.sql.Timestamp; import java.util.Date; /** * Created by del-b ...
- yum安装Mysql-5.6
MySQL yum库提供了一个简单的和方便的方法来安装和更新MySQL相关的软件包到最新版本. MySQL yum库文档说明:http://dev.mysql.com/doc/mysql-yum-re ...
- LeetCode517. Super Washing Machines
You have n super washing machines on a line. Initially, each washing machine has some dresses or is ...
- Celery 框架学习笔记(生产者消费者模式)
生产者消费者模式 在实际的软件开发过程中,经常会碰到如下场景:某个模块负责产生数据,这些数据由另一个模块来负责处理(此处的模块是广义的,可以是类.函数.线程.进程等).产生数据的模块,就形象地称为生产 ...
- 如何读取Hadoop中压缩的文件
最近在处理离线数据导入HBase的问题,涉及从Hdfs中读取gz压缩文件,把思路记录下来,以作备用.具体代码如下: package org.dba.util; import java.io.Buffe ...