DP+线段树维护矩阵(2019牛客暑期多校训练营(第二场))--MAZE
题意:https://ac.nowcoder.com/acm/contest/882/E
给你01矩阵,有两种操作:1是把一个位置0变1、1变0,2是问你从第一行i开始,到最后一行j有几种走法。你只能不能向上走而且不能往回走。
思路:
01矩阵里每一行可以用一个矩阵表示向下有几种走法,i行到j行的的走法就是各行的矩阵的乘积。用线段树维护即可。
线段树seg【1】的【x】【y】就是答案。
#define IOS ios_base::sync_with_stdio(0); cin.tie(0);
#include <cstdio>//sprintf islower isupper
#include <cstdlib>//malloc exit strcat itoa system("cls")
#include <iostream>//pair
#include <fstream>//freopen("C:\\Users\\13606\\Desktop\\Input.txt","r",stdin);
#include <bitset>
//#include <map>
//#include<unordered_map>
#include <vector>
#include <stack>
#include <set>
#include <string.h>//strstr substr strcat
#include <string>
#include <time.h>// srand(((unsigned)time(NULL))); Seed n=rand()%10 - 0~9;
#include <cmath>
#include <deque>
#include <queue>//priority_queue<int, vector<int>, greater<int> > q;//less
#include <vector>//emplace_back
//#include <math.h>
#include <cassert>
#include <iomanip>
//#include <windows.h>//reverse(a,a+len);// ~ ! ~ ! floor
#include <algorithm>//sort + unique : sz=unique(b+1,b+n+1)-(b+1);+nth_element(first, nth, last, compare)
using namespace std;//next_permutation(a+1,a+1+n);//prev_permutation
//******************
clock_t __STRAT,__END;
double __TOTALTIME;
void _MS(){__STRAT=clock();}
void _ME(){__END=clock();__TOTALTIME=(double)(__END-__STRAT)/CLOCKS_PER_SEC;cout<<"Time: "<<__TOTALTIME<<" s"<<endl;}
//***********************
#define rint register int
#define fo(a,b,c) for(rint a=b;a<=c;++a)
#define fr(a,b,c) for(rint a=b;a>=c;--a)
#define mem(a,b) memset(a,b,sizeof(a))
#define pr printf
#define sc scanf
#define ls rt<<1
#define rs rt<<1|1
typedef pair<int,int> PII;
typedef vector<int> VI;
typedef long long ll;
const double E=2.718281828;
const double PI=acos(-1.0);
const ll INF=(1LL<<);
const int inf=(<<);
const double ESP=1e-;
const int mod=(int)1e9+;
const int N=(int); int n,m,q;
char a[N][];
int fa[];
void init()
{
for(int i=;i<=;++i)
fa[i]=i;
}
int Find(int x)
{
return (x==fa[x])?x:(fa[x]=Find(fa[x]));
} void combine(int a,int b)
{
int temp_a,temp_b; temp_a=Find(a);
temp_b=Find(b); if(temp_a!=temp_b)
{
if(temp_a<temp_b)
fa[temp_b]=temp_a;
else
fa[temp_a]=temp_b;
}
} struct Mat
{
ll a[][];
}seg[N<<],e,n1;
Mat mul(Mat x,Mat y)
{
Mat c=Mat();
for(int i=;i<=;++i)
{
for(int j=;j<=;++j)
{
for(int k=;k<=;++k)
c.a[i][j]+=(x.a[i][k]*y.a[k][j])%mod,c.a[i][j]%=mod;
}
}
return c;
}
void up(int rt,int l,int r)
{
seg[rt]=mul(seg[ls],seg[rs]);
} void Build(int l,int r,int rt)
{
if(l==r)
{
init();
for(int j=;j<=m;++j)
{
if(j<m&&a[l][j]==''&&a[l][j+]=='')
combine(j,j+);
}
seg[rt]=Mat();
for(int j=;j<=m;++j)
for(int k=;k<=m;++k)
if(a[l][j]==''&&a[l][k]==''&&Find(j)==Find(k))
seg[rt].a[j][k]=;
return;
}
int mid=(l+r)>>; Build(l,mid,rt<<);
Build(mid+,r,rt<<|);
up(rt,l,r);
} void update_dot(int pos,Mat V,int l,int r,int rt)
{
if(l==r)
{
seg[rt]=V;
return;
} int mid=(l+r)>>;
if(pos<=mid)
update_dot(pos,V,l,mid,rt<<);
else
update_dot(pos,V,mid+,r,rt<<|);
up(rt,l,r);
} int main()
{
e=n1=Mat();
for(int i=;i<=;++i)
e.a[i][i]=,n1.a[][i]=;
sc("%d%d%d",&n,&m,&q);
for(int i=;i<=n;++i)
sc("%s",a[i]+);
Build(,n,);
for(int i=;i<=q;++i)
{
int op,x,y;
sc("%d%d%d",&op,&x,&y);
if(op==)
{
a[x][y]^=;
init();
for(int j=;j<=m;++j)
{
if(j<m&&a[x][j]==''&&a[x][j+]=='')
combine(j,j+);
}
Mat temp=Mat();
for(int j=;j<=m;++j)
for(int k=;k<=m;++k)
if(a[x][j]==''&&a[x][k]==''&&Find(j)==Find(k))
temp.a[j][k]=;
update_dot(x,temp,,n,);
}
else
pr("%lld\n",seg[].a[x][y]);
}
return ;
} /**************************************************************************************/
DP+线段树维护矩阵(2019牛客暑期多校训练营(第二场))--MAZE的更多相关文章
- 2019牛客暑期多校训练营(第二场) H-Second Large Rectangle(单调栈)
题意:给出由01组成的矩阵,求求全是1的次大子矩阵. 思路: 单调栈 全是1的最大子矩阵的变形,不能直接把所有的面积存起来然后排序取第二大的,因为次大子矩阵可能在最大子矩阵里面,比如: 1 0 0 1 ...
- 2019牛客暑期多校训练营(第九场) D Knapsack Cryptosystem
题目 题意: 给你n(最大36)个数,让你从这n个数里面找出来一些数,使这些数的和等于s(题目输入),用到的数输出1,没有用到的数输出0 例如:3 4 2 3 4 输出:0 0 1 题解: 认真想一 ...
- 2020牛客暑期多校训练营 第二场 C Cover the Tree 构造 贪心
LINK:Cover the Tree 最受挫的是这道题,以为很简单 当时什么都想不清楚. 先胡了一个树的直径乱搞的贪心 一直过不去.后来意识到这类似于最经典长链剖分优化贪心的做法 然后那个是求最大值 ...
- 2020牛客暑期多校训练营 第二场 B Boundary 计算几何 圆 已知三点求圆心
LINK:Boundary 计算几何确实是弱项 因为好多东西都不太会求 没有到很精通的地步. 做法很多,先说官方题解 其实就是枚举一个点 P 然后可以发现 再枚举一个点 然后再判断有多少个点在圆上显然 ...
- 2020牛客暑期多校训练营 第二场 A All with Pairs 字符串hash KMP
LINK:All with Pairs 那天下午打这个东西的时候状态极差 推这个东西都推了1个多小时 (比赛是中午考试的我很困 没睡觉直接开肝果然不爽 一开始看错匹配的位置了 以为是\(1-l\)和\ ...
- 2020牛客暑期多校训练营 第二场 K Keyboard Free 积分 期望 数学
LINK:Keyboard Free 我要是会正经的做法 就有鬼了. 我的数学水平没那么高. 三个同心圆 三个动点 求围成三角形面积的期望. 不会告辞. 其实可以\(n^2\)枚举角度然后算出面积 近 ...
- 2020牛客暑期多校训练营 第二场 J Just Shuffle 置换 群论
LINK:Just Shuffle 比较怂群论 因为没怎么学过 置换也是刚理解. 这道题是 已知一个置换\(A\)求一个置换P 两个置换的关键为\(P^k=A\) 且k是一个大质数. 做法是李指导教我 ...
- 2020牛客暑期多校训练营 第二场 I Interval 最大流 最小割 平面图对偶图转最短路
LINK:Interval 赛时连题目都没看. 观察n的范围不大不小 而且建图明显 考虑跑最大流最小割. 图有点稠密dinic不太行. 一个常见的trick就是对偶图转最短路. 建图有点复杂 不过建完 ...
- 2019牛客暑期多校训练营(第五场)G - subsequeue 1 (一题我真的不会的题)
layout: post title: 2019牛客暑期多校训练营(第五场)G - subsequeue 1 (一题我真的不会的题) author: "luowentaoaa" c ...
- 2019牛客暑期多校训练营(第二场)-E MAZE
题目链接:https://ac.nowcoder.com/acm/contest/882/E 题意:n×m的矩阵,0表示可以走,1表示墙,不能通过.有q中操作,一种是改变坐标(x,y)的状态,一种是询 ...
随机推荐
- openstack 本地导入镜像.
网络很慢,直接本地传. openstack image create "Fedora30" --file Fedora-Cloud-Base-30-1.2.x86_64.qcow2 ...
- 微服务springboot视频最新SpringBoot2.0.3版本技术视频教程【免费学习】
超火爆的springboot微服务技术怎么学,看这里,springboot超详细的教程↓↓↓↓↓↓https://ke.qq.com/course/179440?tuin=9b386640 01.sp ...
- 算法的时间复杂度——"大O分析法"(转载)
原文地址:https://my.oschina.net/gooke/blog/684026 一下为本人笔记:) 场景:在解决计算机科学领域的问题时,经常有好多个方法都可以,想找到最优的方法,就有了时间 ...
- pod package 生成 Framework
pod package 生成 Framework pod package 是 cocoapods 的一个插件,如果没有的话使用以下命令安装: sudo gem install cocoapods-pa ...
- Javascript中数组查重的方法总结大全
数组查重:简单点说,就是找出数组中重复的元素然后去除,最后得到一个没有重复元素的数组. // 方法一思路: 1.构建一个新的数组,用于存放结果. 2.for循环中每次从数组取出一个 ...
- 002-jdk-数据结构-工具类Collections、Arrays、System.arraycopy
常用备注 一.LIst to Array List<String> list = new ArrayList<String>(); Object[] array=list.to ...
- OpenStack 虚拟机热迁移流程图
目录 文章目录 目录 源计算节点与目的计算节点之间的交互流程 Nova 和 Neutron 之间的交互流程 源计算节点与目的计算节点之间的交互流程 热迁移主要包括三个阶段: pre_live_migr ...
- Flutter 实现简单搜索功能
先建立一个主文件,继承StatelessWidget,然后在home属性中加入SearchBarDemo,这是一个自定义的Widget,主要代码都在这个文件中. import 'package:flu ...
- linux下使用openssl和md5sum加密文件或者字符串
#openssl //在终端中输入openssl后回车. OpenSSL> md5 //输入md5后回车 123456 //接着输入123456,不要输入回车.然后按3次ctr ...
- Cracking the coding interview目录及资料收集
前言 <Cracking the coding interview>是一本被许多人极力推荐的程序员面试书籍, 详情可见:http://www.careercup.com/book. 第六版 ...