[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 ...
随机推荐
- Multiple HTTPS Bindings IIS 7 Using appcmd
http://toastergremlin.com/?p=308 Sometimes when using a wildcard SSL or Unified Communications Certi ...
- Dream------Hadoop--Hadoop HA QJM (Quorum Journal Manager)
In a typical HA cluster, two separate machines are configured as NameNodes. At any point in time, ex ...
- 79.ZYNQ内部私有定时器中断
上篇文章实现了了PS接受来自PL的中断,本片文章将在ZYNQ的纯PS里实现私有定时器中断.每个一秒中断一次,在中断函数里计数加1,通过串口打印输出. *本文所使用的开发板是Miz702(兼容zedbo ...
- Vagrant 无法校验手动下载的 Homestead Box 版本
起因 4年前电脑,配置不太好了,现有的 Homestead 运行起来太吃内存.在修改了 Homestead.yaml 文件里 memory 选项的内存配置为 1024 后,应用最新配置重启失败. 索性 ...
- linux查看目录的四种方法(ls只显示目录)【转】
1.ls -d * amosli@amosli-pc:~$ ls -d * %APPDATA% develop many sorted.txt workspace bank Documents Mus ...
- openjudge-NOI 2.5-1700 八皇后问题
题目链接:http://noi.openjudge.cn/ch0205/1700/ 题解: 经典深搜题目…… #include<cstdio> ][]; int num; void pri ...
- MySQL 联合查询
联合查询:将多次查询(多条select语句), 在记录上进行拼接(字段不会增加) 基本语法:多条select语句构成: 每一条select语句获取的字段数必须严格一致(但是字段类型无关) 语法 Sel ...
- docker stack 部署 filebeat
=============================================== 2018/7/21_第3次修改 ccb_warlock 更新 ...
- python基础-类的封装
封装:类中封装了公有属性和方法,对象封装了私有属性的值 class F1: def __init__(self,n): self.N=n print('F') class F2: def __init ...
- RESTful API 和 Django REST framework
100天 cmdb最后一天 #RESTful API - 定义规范 如get就是请求题 - 面向资源编程 把网络任何东西都当作资源 #给一个url,根据方法的不同对资源做不同的操作 #返回结果和状态码 ...