hdu 5068 线段树加+dp
这题说的是 有n 层每层 有两个门 每个门 可以到达上一层的两个门,然后求从a 层到达b 层的方案总数, 不能后退, 在同一层中不能从第一个门到达另一层
我们只要我们可以对于每个 区间内 有dp[o][2][2] , 表示 在这个区间中 从区间起始到达区间末尾 的两个门分别设 a1,a2, b1,b2, dp[o][0][0],和dp[o][0][1],表示从从a1到b1 和 a2 到 b1 的方案总数 然后同理dp[o][1][0]dp[o][1][1],
得到转移 通过线段树去优化他 得到转移 一旦ij 两地相通那么显然 i这个点 的 在前面这个区间的a1 a2 相应的乘上 后面 这个区间在 j 这个位置开始的方案总数, 得到他们在总区间结束时的在 b1上有多少个方案从前面区间的 a1 和a2 过来,通过这样得到整个区间的值
for(int i=; i<; ++i)
for(int j=; j<; ++j)
if(star[mid][i][j]){
value[o].M[][]=(value[o].M[][] + value[o*].M[i][] * value[o*+].M[][j] % mod )%mod;
value[o].M[][]=(value[o].M[][] + value[o*].M[i][] * value[o*+].M[][j]%mod )%mod;
value[o].M[][]=(value[o].M[][] + value[o*].M[i][] * value[o*+].M[][j]%mod )%mod;
value[o].M[][]=(value[o].M[][] + value[o*].M[i][] * value[o*+].M[][j]%mod )%mod;
}
#include <iostream>
#include <cstdio>
#include <string.h>
using namespace std;
typedef __int64 ll;
const int maxn = ;
const ll mod = ;
int loc,x,y;
struct Matx{
ll M[][];
}P;
bool star[maxn+][][];
void maintain(int mid ,Matx &A,Matx B){
Matx ans;
memset(ans.M,,sizeof(ans.M));
for(int i=; i<; ++i)
for(int j=; j<; ++j)
if(star[mid][i][j]){
ans.M[][]=(ans.M[][] + A.M[i][] * B.M[][j] )%mod;
ans.M[][]=(ans.M[][] + A.M[i][] * B.M[][j] )%mod;
ans.M[][]=(ans.M[][] + A.M[i][] * B.M[][j] )%mod;
ans.M[][]=(ans.M[][] + A.M[i][] * B.M[][j] )%mod;
}
for(int i=; i<; ++i)
for(int j=; j<; ++j)
A.M[i][j]=ans.M[i][j];
}
struct Itree{
Matx value[maxn*]; void tain(int o,int mid){
memset(value[o].M,,sizeof(value[o].M));
for(int i=; i<; ++i)
for(int j=; j<; ++j)
if(star[mid][i][j]){
value[o].M[][]=(value[o].M[][] + value[o*].M[i][] * value[o*+].M[][j] % mod )%mod;
value[o].M[][]=(value[o].M[][] + value[o*].M[i][] * value[o*+].M[][j]%mod )%mod;
value[o].M[][]=(value[o].M[][] + value[o*].M[i][] * value[o*+].M[][j]%mod )%mod;
value[o].M[][]=(value[o].M[][] + value[o*].M[i][] * value[o*+].M[][j]%mod )%mod;
}
}
void build(int o, int L, int R){
if(L==R){
value[o].M[][]=;
value[o].M[][]=;
value[o].M[][]=;
value[o].M[][]=;
for(int i=; i<; ++i)
for(int j=; j<; ++j)
star[L][i][j]=true;
return ;
}
int mid= (L+R)/;
build( o* , L , mid );
build( o*+ , mid+ , R );
tain(o,mid);
} void update(int o, int L, int R){
if(L==R){
star[L][x][y]=star[L][x][y]==false;
return ;
}
int mid=(L+R)/;
if(loc<=mid) update(o*,L,mid);
else update(o*+,mid+,R);
tain(o, mid);
}
void query(int o, int L, int R){
if( (L>=x&&R<=y) ){
if(loc==){
P=value[o];loc=;
}else{
maintain(L-,P,value[o]);
}
return ;
}
int mid = (L+R)/;
if(x<=mid)
query(o*,L,mid);
if(y>mid)
query(o*+,mid+,R);
}
}T;
int main()
{
int n,m;
while(scanf("%d%d",&n,&m)==){
T.build(,,n);
for(int i=; i<m; ++i){
loc=;
int op;
scanf("%d",&op);
if(op==) {
scanf("%d%d",&x,&y);
T.query(,,n);
ll ans=;
for(int i=; i<; ++i)
for(int j=; j<; ++j)
ans=(ans+ P.M[i][j])%mod;
printf("%I64d\n",ans);
}else{
scanf("%d%d%d",&loc,&x,&y);
x--; y--;
T.update(,,n);
}
}
}
return ;
}
hdu 5068 线段树加+dp的更多相关文章
- hdu 5068 线段树维护矩阵乘积
http://acm.hdu.edu.cn/showproblem.php?pid=5068 题意给的略不清晰 m个询问:从i层去j层的方法数(求连段乘积)或者修改从x层y门和x+1层z门的状态反转( ...
- hdu 5068(线段树+矩阵乘法)
矩阵乘法来进行所有路径的运算, 线段树来查询修改. 关键还是矩阵乘法的结合律. Harry And Math Teacher Time Limit: 5000/3000 MS (Java/Others ...
- hdu 4533 线段树(问题转化+)
威威猫系列故事——晒被子 Time Limit: 3000/1000 MS (Java/Others) Memory Limit: 65535/32768 K (Java/Others) Tot ...
- hdu 1542 线段树扫描(面积)
Atlantis Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others)Total Su ...
- hdu 1166 线段树(sum+单点修改)
敌兵布阵 Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others) Total Submi ...
- Codeforces 834D The Bakery 【线段树优化DP】*
Codeforces 834D The Bakery LINK 题目大意是给你一个长度为n的序列分成k段,每一段的贡献是这一段中不同的数的个数,求最大贡献 是第一次做线段树维护DP值的题 感觉还可以, ...
- 【题解】P4247 [清华集训]序列操作(线段树修改DP)
[题解]P4247 [清华集训]序列操作(线段树修改DP) 一道神仙数据结构(DP)题. 题目大意 给定你一个序列,会区间加和区间变相反数,要你支持查询一段区间内任意选择\(c\)个数乘起来的和.对1 ...
- 【POJ 2750】 Potted Flower(线段树套dp)
[POJ 2750] Potted Flower(线段树套dp) Time Limit: 2000MS Memory Limit: 65536K Total Submissions: 4566 ...
- 洛谷$P2605\ [ZJOI2010]$基站选址 线段树优化$dp$
正解:线段树优化$dp$ 解题报告: 传送门$QwQ$ 难受阿,,,本来想做考试题的,我还造了个精妙无比的题面,然后今天讲$dp$的时候被讲到了$kk$ 先考虑暴力$dp$?就设$f_{i,j}$表示 ...
随机推荐
- 【RF库Collections测试】Get Index From List
Name:Get Index From ListSource:Collections <test library>Arguments:[ list_ | value | start=0 | ...
- 制作Windows U盘镜像
目的:制作windows server 2008 U盘镜像 需要的共具: 1.一个格式为FAT并且至少4G的U盘, 2.UltraISO软件, 3.一个windows server 2008 ISO文 ...
- 一个java源文件中是否可以包括多个类(非内部类)?有何限制?
可以有多个类,但只能有一个public的类,并且public的类名必须与文件名一致.
- 【thinkphp5】 分页样式修改
1 找到文件:/thinkphp/library/think/paginator/driver/Bootstrap.php <?php // +------------------------- ...
- LNMP redis 安装、PHPredis扩展配置、服务器自启动、redis认证密码
背景: LNMP 环境(centos7) 一. 安装redis 1.下载,解压,编译 $ cd /usr/local$ wget http://download.redis.io/releases/r ...
- SpringData JPA查询分页demo
SpringData JPA 的 PagingAndSortingRepository接口已经提供了对分页的支持,查询的时候我们只需要传入一个 org.springframework.data.dom ...
- 【BZOJ1787】[Ahoi2008]Meet 紧急集合 LCA
[BZOJ1787][Ahoi2008]Meet 紧急集合 Description Input Output Sample Input 6 4 1 2 2 3 2 4 4 5 5 6 4 5 6 6 ...
- ThinkPHP简单结构介绍!
thinkPHP简单结构介绍: application : 应用 extend:扩展 扩展内库 public:入口文件 index.php 在里面 runtime:缓存文件(里面的文件可以随便删除) ...
- oracle数据库实例状态
1.已启动/不装载(NOMOUNT).启动实例,但不装载数据库. 该模式用于重新创建控制文件,对控制文件进行恢复或重新创建数据库.2.已装载(MOUNT).装载数据库,但不打开数据库. 该模式用于更改 ...
- Linux系统下Nginx+PHP 环境安装配置
一.编译安装Nginx 官网:http://wiki.nginx.org/Install 下载:http://nginx.org/en/download.html # tar -zvxf nginx- ...