[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 ...
随机推荐
- datatable表格框架服务器端分页查询设置
更多内容推荐微信公众号,欢迎关注: js代码如下: $('#mytable').dataTable( { "bServerSide": true, //开启服务器模式,使用服务器端 ...
- vue开发者工具vue-devtools-4.1.4_0.crx谷歌插件下载及安装
网盘地址: https://pan.baidu.com/s/14PoaihUHQZEJtiHNWUmdjg 下载好后 谷歌浏览器中扩展程序,开启开发者模式,将下载的文件拖到窗口中即可 然后重启浏览器 ...
- 20165320 实验一 java环境的熟悉
实验内容与步骤 一.java开发环境的熟悉 1.建立一个有关自己学号的目录 2.在当前文件下编译一个带包Hello.java文件 3.代码内容 package sq; import java.util ...
- CodeForces 1096E: The Top Scorer
一道经典组合数学+容斥题. 题目传送门:CF1096E. 题意简述: \(p\) 个人,每个人有得分 \(a_i\). 总得分 \(\sum a_i = s\). 第一个人得分 \(a_1 \ge r ...
- TCP/IP详解(整理)
1.概述 路由器是在网络层进行联通,而网桥是在链路层联通不同的网络. IP层用ICMP来与其他主机或路由器交换错误报文和其他的重要信息.应用程序也可以访问ICMP,两个诊断工具:Ping和Tracer ...
- Failed to execute 'setRequestHeader' on 'XMLHttpRequest': The object's state must be OPENED.
在设置请求头的时候报这个Failed to execute 'setRequestHeader' on 'XMLHttpRequest': The object's state must be OPE ...
- idea添加jdbc包
IDEA版本:IDEA 14 这里我使用的第三方jar包是数据库的JDBC jar包导出案例. 1.创建一个Module,名称为dataBase,在里面我们先创建一个folder用来包含所需要的jar ...
- Scrapy项目之User timeout caused connection failure(异常记录)
Windows 10家庭中文版,Python 3.6.4,Scrapy 1.5.0, 提示:此文存在问题,真正测试, 请勿阅读, 07-14 14:26更新: 经过两个多小时的测试,发现此问题的原因是 ...
- XP远程连接Win10,提示【远程计算机需要网络级别身份验证,而您的计算机不支持该验证】
最近电脑安装了Win10系统,在办公室可以通过其他电脑远程,但是回去后使用自己的电脑(XP系统)进行远程提示失败, 提示[远程计算机需要网络级别身份验证,而您的计算机不支持该验证],然后上网查找资料, ...
- Java与redis交互、Jedis连接池JedisPool
Java与redis交互比较常用的是Jedis. 先导入jar包: commons-pool2-2.3.jar jedis-2.7.0.jar 基本使用: public class RedisTest ...