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

  1. 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] + ...

  2. HDU 6155 Subsequence Count 线段树维护矩阵

    Subsequence Count Time Limit: 10000/5000 MS (Java/Others)    Memory Limit: 256000/256000 K (Java/Oth ...

  3. Wannafly Winter Camp 2019.Day 8 div1 E.Souls-like Game(线段树 矩阵快速幂)

    题目链接 \(998244353\)写成\(99824435\)然后调这个线段树模板1.5h= = 以后要注意常量啊啊啊 \(Description\) 每个位置有一个\(3\times3\)的矩阵, ...

  4. Codeforces 750E - New Year and Old Subsequence(线段树维护矩阵乘法,板子题)

    Codeforces 题目传送门 & 洛谷题目传送门 u1s1 我做这道 *2600 的动力是 wjz 出了道这个套路的题,而我连起码的思路都没有,wtcl/kk 首先考虑怎样对某个固定的串计 ...

  5. CF719E(线段树+矩阵快速幂)

    题意:给你一个数列a,a[i]表示斐波那契数列的下标为a[i],求区间对应斐波那契数列数字的和,还要求能够维护对区间内所有下标加d的操作 分析:线段树 线段树的每个节点表示(f[i],f[i-1])这 ...

  6. 【Codeforces718C】Sasha and Array 线段树 + 矩阵乘法

    C. Sasha and Array time limit per test:5 seconds memory limit per test:256 megabytes input:standard ...

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

  8. 线段树 + 矩阵 --- ZOJ 3772 Calculate the Function

    Calculate the Function Problem's Link:   http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemCod ...

  9. FZU 2105 Digits Count(线段树)

    Problem 2105 Digits Count Accept: 302 Submit: 1477 Time Limit: 10000 mSec Memory Limit : 262144 KB P ...

随机推荐

  1. JavaScript中函数参数的值传递和引用传递

    结论: 对于数字.字符串等基本类型变量,是将它们的值传递给了函数参数,函数参数的改变不会影响函数外部的变量. 对于数组和对象等是将对象(数组)的变量的值传递给了函数参数,这个变量保存的指向对象(数组) ...

  2. pywin32记录备忘

    项目地址:http://sourceforge.net/projects/pywin32/ 文档地址:http://docs.activestate.com/activepython/2.7/pywi ...

  3. Oracle基础结构认知—初识oracle【转】

    Oracle服务器(oracle server)由实例和数据库组成.其中,实例就是所谓的关系型数据库管理系统(Relational Database Management System,RDBMS), ...

  4. c# List 所有操作方法例子

    using System; using System.Collections.Generic; using System.IO; using System.Linq; using System.Ref ...

  5. avalonJS-源码阅读(一)

    写angularJS源码阅读系列的时候,写的太垃圾了.一个月后看,真心不忍直视,以后有机会的话得重写.这次写avalonJS,希望能在代码架构层面多些一点,少上源码.多写思路. avalon暴露句柄方 ...

  6. ETL利器Kettle实战应用解析系列三

    本系列文章主要索引如下: 一.ETL利器Kettle实战应用解析系列一[Kettle使用介绍] 二.ETL利器Kettle实战应用解析系列二 [应用场景和实战DEMO下载] 三.ETL利器Kettle ...

  7. 『实践』百度地图给map添加右键菜单(判断是否为marker)

      var map; var s;//经度 var w;//纬度 $(document).ready(function(){ $(".mune").load("jsp/c ...

  8. IIS 启用https

    参考:http://www.cnblogs.com/dudu/p/iis_https_ca.html

  9. 简单ORACLE分区表、分区索引

    前一段听说CSDN.COM里面很多好东西,同事建议看看合适自己也可以写一写,呵呵,今天第一次开通博客,随便写点东西,就以第一印象分区表简单写第一个吧. ORACLE对于分区表方式其实就是将表分段存储, ...

  10. 追MM与设计模式

    1.FACTORY—追MM少不了请吃饭了,麦当劳的鸡翅和肯德基的鸡翅都是MM爱吃的东西,虽然口味有所不同,但不管你带MM去麦当劳或肯德基,只管向服务员说“来四个鸡翅”就行了.麦当劳和肯德基就是生产鸡翅 ...