题目

n*m(1<=n,m<=2e5,n*m<=2e5)的网格图,

有一些格子内已经放入了闹钟,当前时刻在[0,h)(1<=h<=1e9)之间

还有一些位置没有放闹钟,输入时用-1表示,

在放入这些闹钟的时候,你可以指定它们的初始时刻,只要在[0,h)即可

不同的闹钟,被指定的初始时刻可以不同

放完这些闹钟之后,你可以执行以下操作若干次,

每次选择一行或者一列,并将这些闹钟都往后调一个小时,

即,当前闹钟时刻x,x<h-1时,会被调到x+1;x=h-1时,会被调到0

求指定初始时刻的方案数,使得所有的闹钟可以被调到同一时刻,答案对1e9+7取模

实际用例总数t不超过5e4,但保证sum n*m<2e5

思路来源

乱搞ac

题解

其实和刚刚的abc280f很像,只是这个题更直接一些,

都有在线和离线两种做法,感觉很典中典

在线:带权并查集(hdu3047);离线:建树然后dfs判环(abc280f)

而abc280f这个题,主要是要找出非零环,

于是对图dfs得到一棵树后,检查非树边是否可以被树边线性表示

这个题也可以采用一样的做法,将同一行内的,值不为-1的两列,x列和y列,

连边y->x,权值(val[y]-val[x])%h;连边x->y,权值(val[x]-val[y])%h,就化成了abc280f这个题

于是只需检查,不同行对于列的限制,是否存在矛盾即可

对每一行做完之后,每一列就无需再做一遍了,

因为如果行的限制满足,势必存在一个delta,

使得第一行的x列的数,加delta后,等于第二行的x列的数;

第一行的y列的数,加delta后,等于第二行的y列的数;

检查完没有矛盾之后,

对于确定的数(不是-1的数)所在的位置(x,y),就直接将x行和y列这两个点直接连到一起,

连到一起后,当前图相当于被分成了若干个连通块,

而每将-1填成一个具体的数,都有h种选择,

并且,将(x,y)处的-1填成具体数后,

相当于将x行所在的联通和y列所在的连通块合并到一起

最后,需要将n行m列这n+m个点合并成一个连通块

设通过-1合并了x次,则答案为h的x次方,

感觉有点类似矩阵的秩

代码

#include<iostream>
#include<cstdio>
#include<cstring>
#include<vector>
using namespace std;
typedef long long ll;
const int maxn=4e5+10,mod=1e9+7;
int t,n,m,h,par[maxn];
ll pos[maxn];
void init(int x){for(int i=0;i<x;++i){par[i]=i;pos[i]=0;}
}
int find(int x){if(par[x]==x)return x;int fa=par[x];//直接基类 par[x]=find(par[x]);//路径压缩 (pos[x]+=pos[fa])%=h;//树上前缀和 两链变一链 直接连树根 return par[x];//返回树根
}
//y比x大v
bool unite(int x,int y,ll v){int px=find(x),py=find(y);if(px==py){if((pos[x]+v-pos[y])%h)return 0;return 1;}//把y所在树的树根挂在x所在树的树根上 只改树根py par[py]=px;//rank[py]=rank[y现在]-rank[y之前]==(rank[x]+v)-rank[y] pos[py]=((pos[x]+v-pos[y])%h+h)%h;//注意rank可能有负 与将负旋为0的根是等价的return 1;
}
int solve(){vector<vector<ll> >a(n+1,vector<ll>(m+1,0));int all=0,cnt=0;init(m);for(int i=0;i<n;++i){for(int j=0;j<m;++j){scanf("%lld",&a[i][j]);}}for(int i=0;i<n;++i){int las=-1;for(int j=0;j<m;++j){if(a[i][j]==-1)continue;if(~las && !unite(las,j,(a[i][j]-a[i][las]+h)%h)){return 0;}las=j;}}/*init(n);for(int j=0;j<m;++j){int las=-1;for(int i=0;i<n;++i){if(a[i][j]==-1)continue;if(~las && !unite(las,i,a[i][j]-a[las][j])){return 0;}las=i;}}*/init(n+m);for(int i=0;i<n;++i){for(int j=0;j<m;++j){if(~a[i][j])par[find(n+j)]=find(i);}}for(int i=0;i<n+m;++i){if(find(i)==i)cnt++;}int res=1;for(int i=1;i<cnt;++i){res=1ll*h*res%mod;}//printf("res:%d h:%d\n",res,h);//printf("res:%d\n",res);return res;
}
int main(){scanf("%d",&t);for(int i=1;i<=t;++i){scanf("%d%d%d",&n,&m,&h);printf("%d\n",solve());}return 0;
}
/*
hdu3047 带权并查集
1 2
-1 -11 -1
-1 21 0 -1
-1 -1 2n+m-1个点 现在有3个点-1 -1 -1
-1 -1 -1
n+m-1个点 现在有0个点
*/

Codeforces Round #836 (Div. 2) E.Tick, Tock(在线:带权并查集/离线:dfs判环)相关推荐

  1. Valentine's Day Round hdu 5176 The Experience of Love [好题 带权并查集 unsigned long long]

    传送门 The Experience of Love Time Limit: 4000/2000 MS (Java/Others)    Memory Limit: 65536/65536 K (Ja ...

  2. Codeforces Round #836 (Div. 2) A~E

    A. SSeeeeiinngg DDoouubbllee 一个字符串正着输出一遍,反正输出一遍就好了. #include <bits/stdc++.h> #define FOR(i,a,b ...

  3. *【CodeForces - 791B】Bear and Friendship Condition (图论,判断完全图,dfs乱搞或带权并查集)

    题干: Bear Limak examines a social network. Its main functionality is that two members can become frie ...

  4. Codeforces Round #396(Div. 2)

    Codeforces Round #396 A. Mahmoud and Longest Uncommon Subsequence 题意 给定两串,求最长非公共子串. 非公共子串:A串的某子串sub_ ...

  5. Codeforces round 396(Div. 2) 题解

    Problem A 题目大意 给定两个字符串,要求构造出一个最长的一个串满足:这个串是其中一个串的字序列并且不是另一个串的子序列.输出长度.\((len \leq 10^5)\) 题解 千万年死在读题 ...

  6. Codeforces Round #506 (Div. 3)

    Codeforces Round #506 (Div. 3) 实习期间事不多,对div3 面向题解和数据编程了一波 A. Many Equal Substrings 题目链接 A题就是找后缀和前缀重合 ...

  7. Codeforces Round #563 (Div. 2)/CF1174

    Codeforces Round #563 (Div. 2)/CF1174 CF1174A Ehab Fails to Be Thanos 其实就是要\(\sum\limits_{i=1}^n a_i ...

  8. 构造 Codeforces Round #302 (Div. 2) B Sea and Islands

    题目传送门 1 /* 2 题意:在n^n的海洋里是否有k块陆地 3 构造算法:按奇偶性来判断,k小于等于所有点数的一半,交叉输出L/S 4 输出完k个L后,之后全部输出S:) 5 5 10 的例子可以 ...

  9. Codeforces Round #696 (Div. 2) (A ~ E)超高质量题解(每日训练 Day.16 )

    整理的算法模板合集: ACM模板 点我看算法全家桶系列!!! 实际上是一个全新的精炼模板整合计划 Codeforces Round #696 (Div. 2) (A ~ E)超高质量题解 比赛链接:h ...

最新文章

  1. 人工智能(Artificial Intelligence)常用算法
  2. Java多线程2:Thread中的实例方法
  3. python数据结构树和二叉树,python数据结构树和二叉树简介
  4. linux 下screen命令
  5. 关于清单,有几点我觉得比较重要。
  6. 思科IPS系统的bypass mode
  7. 605. 种花问题003(贪心算法+思路+详解)
  8. 最全Java架构师130面试题:微服务、高并发、大数据、缓存等中间件
  9. mysql 字段值不同枚举_【mysql】关于枚举值 '1','0'的神奇判断
  10. MySQL VARCHAR的说明信息
  11. Java练习例子:计算圆柱体积
  12. DSP技术-2-DSP的C语言同主机C语言的主要区别在哪里?
  13. h5 Table表格
  14. 开发一款APP都有哪些流程?
  15. ThinkPad键盘失灵解决办法
  16. mysql error1205 博客_MySQL的ERROR 1205错误分析
  17. 第十一届“挑战杯”广东省大学生课外学术科技作品竞赛总结——谢凌云
  18. 一个免费开源、跨平台的可视化源码探索项目
  19. 【线性代数】矩阵及其特性
  20. 微信小程序云数据库请求数据并将请求到的数据显示到小程序页面上

热门文章

  1. 小米感谢米粉选择环保版小米11,但喜欢环保的米粉实在少之又少
  2. FLASH AS3.0监听事件
  3. 日语助词を的所有的语法点,请牢记
  4. 剖析中国软件百强收藏
  5. 小觅相机初始化(标准版)
  6. rank函数的使用计算机考试,计算机函数rank的用法
  7. 一般如何实现快速建站?
  8. 计算机二级accesse有哪些内容,二级Access数据库大纲知识要点
  9. Vue顶部进度条工具nprogress使用
  10. PIL.JpegImagePlugin.JpegImageFile与numpy.ndarray格式转换