CODE FESTIVAL 2016 qualA Grid and Integers
划年代久远的水
题意
有一个R*C的棋盘,要求在每个格子上填一个非负数,使得对任意一个2*2的正方形区域,左上角和右下角的数字之和等于左下角和右上角的数字之和.有一些格子已经被填上了数字,问现在能否满足要求,输出Yes或No.
R,C<=1e5,已经被填上数字的格子数<=1e5
分析
记i行j列的数字为num[i][j]
假设一个2*2的正方形区域中,左上角,右上角,左下角,右下角依次为a,b,c,d,那么a+d=b+c,也就是说,a-b=c-d,a-c=b-d.
由此我们可以推出这样的结论:
对于任意不同的两行a和b,它们第i列和第j列的数字之差是相同的.即num[a][i]-num[a][j]=num[b][i]-num[b][j]
对于任意不同的两列a和b,它们第i行和第j行的数字之差是相同的.即num[i][a]-num[j][a]=num[i][b]-num[j][b]
于是我们可以用两个带权并查集,分别维护列之间数字之差和行之间数字之差.如果数字之差出现矛盾则无解.同时推出由已知的条件能确定的数值最小的数字,如果这个数字是负数则无解.否则有解.
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
#define GG return puts("No"),0;
const int maxn=100005;
typedef long long ll;
int ufs1[maxn];ll w1[maxn];
int ufs2[maxn];ll w2[maxn];
struct node{
int x,y,val;
void read(){
scanf("%d%d%d",&x,&y,&val);
}
}P[maxn];
bool cmpx(const node &A,const node &B){
return A.x<B.x;
}
bool cmpy(const node &A,const node &B){
return A.y<B.y;
}
int find1(int x){
if(x==ufs1[x])return x;
int rt=find1(ufs1[x]);
w1[x]+=w1[ufs1[x]];
return ufs1[x]=rt;
}
int find2(int x){
if(x==ufs2[x])return x;
int rt=find2(ufs2[x]);
w2[x]+=w2[ufs2[x]];
return ufs2[x]=rt;
}
bool link1(int a,int b,ll w){
if(find1(a)!=find1(b)){
int ra=find1(a),rb=find1(b);
ufs1[ra]=ufs1[rb];
w1[ra]=w+w1[b]-w1[a];
return true;
}else{
return w1[a]==w+w1[b];
}
}
bool link2(int a,int b,ll w){
if(find2(a)!=find2(b)){
int ra=find2(a),rb=find2(b);
ufs2[ra]=ufs2[rb];
w2[ra]=w+w2[b]-w2[a];
return true;
}else{
return w2[a]==w+w2[b];
}
}
ll Min1[maxn],Min2[maxn];
int main(){
int R,C;scanf("%d%d",&R,&C);
for(int i=1;i<=R;++i){
ufs1[i]=i;w1[i]=0;
}
for(int i=1;i<=C;++i){
ufs2[i]=i;w2[i]=0;
}
int n;scanf("%d",&n);
for(int i=1;i<=n;++i)P[i].read();
sort(P+1,P+n+1,cmpx);
for(int i=1;i<n;++i){
if(P[i].x==P[i+1].x){
if(!link2(P[i].y,P[i+1].y,P[i+1].val-P[i].val))GG;
}
}
sort(P+1,P+n+1,cmpy);
for(int i=1;i<n;++i){
if(P[i].y==P[i+1].y){
if(!link1(P[i].x,P[i+1].x,P[i+1].val-P[i].val))GG;
}
}
memset(Min1,0x3f,sizeof(Min1));
memset(Min2,0x3f,sizeof(Min2));
for(int i=1;i<=n;++i){
int rt=find1(P[i].x);
Min1[rt]=min(Min1[rt],P[i].val+w1[P[i].x]);
}
for(int i=1;i<=R;++i){
int rt=find1(i);
Min2[rt]=min(Min2[rt],-w1[i]);
}
for(int i=1;i<=R;++i){
if(ufs1[i]==i&&Min1[i]+Min2[i]<0){
GG;
}
}
memset(Min1,0x3f,sizeof(Min1));
memset(Min2,0x3f,sizeof(Min2));
for(int i=1;i<=n;++i){
int rt=find2(P[i].y);
Min1[rt]=min(Min1[rt],P[i].val+w2[P[i].y]);
}
for(int i=1;i<=C;++i){
int rt=find2(i);
Min2[rt]=min(Min2[rt],-w2[i]);
}
for(int i=1;i<=C;++i){
if(ufs2[i]==i&&Min1[i]+Min2[i]<0)GG;
}
printf("Yes\n");
return 0;
}
CODE FESTIVAL 2016 qualA Grid and Integers的更多相关文章
- 【AtCoder】CODE FESTIVAL 2016 qual A
CODE FESTIVAL 2016 qual A A - CODEFESTIVAL 2016 -- #include <bits/stdc++.h> #define fi first # ...
- 【AtCoder】CODE FESTIVAL 2016 qual B
CODE FESTIVAL 2016 qual B A - Signboard -- #include <bits/stdc++.h> #define fi first #define s ...
- 【AtCoder】CODE FESTIVAL 2016 qual C
CODE FESTIVAL 2016 qual C A - CF -- #include <bits/stdc++.h> #define fi first #define se secon ...
- Atcoder CODE FESTIVAL 2016 Grand Final E - Water Distribution
Atcoder CODE FESTIVAL 2016 Grand Final E - Water Distribution 题目链接:https://atcoder.jp/contests/cf16- ...
- Atcoder CODE FESTIVAL 2016 qual C 的E题 Encyclopedia of Permutations
题意: 对于一个长度为n的排列P,如果P在所有长度为n的排列中,按照字典序排列后,在第s位,则P的value为s 现在给出一个长度为n的排列P,P有一些位置确定了,另外一些位置为0,表示不确定. 现在 ...
- [CODE FESTIVAL 2016]Problem on Tree
题意:给一棵树,对于一个满足以下要求的序列$v_{1\cdots m}$,求最大的$m$ 对$\forall1\leq i\lt m$,路径$(v_i,v_{i+1})$不包含$v$中除了$v_i,v ...
- [CODE FESTIVAL 2016]Encyclopedia of Permutations
题意:给定一个排列,其中有可能有一些未确定的数,求出所有可能的排列的排名之和 首先我们要知道怎么算一个给定排列的排名,设它为$p_{1\cdots n}$ 排名即为比它小的排列数$+1$,对于每一个比 ...
- [CODE FESTIVAL 2016]Distance Pairs
题意:有一个未知的边权为$1$的图,给定所有点到$1$的最短路$a_i$和到$2$的最短路$b_i$,问是否存在这样的图,如果存在,问图中最少有多少条边 先考虑$a_i$,有$a_1=0,a_i\ne ...
- CODE FESTIVAL 2016 Grand Final 题解
传送门 越学觉得自己越蠢--这场除了\(A\)之外一道都不会-- \(A\) 贪心从左往右扫,能匹配就匹配就好了 //quming #include<bits/stdc++.h> #def ...
随机推荐
- [agc001E]BBQ Hard[组合数性质+dp]
Description 传送门 Solution 题目简化后要求的实际上是$\sum _{i=1}^{n-1}\sum _{j=i+1}^{n}C^{A[i]+A[j]}_{A[i]+A[j]+B[i ...
- Entity Framework中的几种加载方式
在Entity Framework中有三种加载的方式,分别是延迟加载,自动加载和显示加载.下面用一个例子来说明:现在有两个表,一个是资料表(Reference),另外一个表是资料分类表 ...
- Kettle定时执行
1,Kettle跨平台使用. 例如:在AIX下(AIX是IBM商用UNIX操作系统,此处在LINUX/UNIX同样适用),运行Kettle的相关步骤如下: 1)进入到Kettle部署的路径 ...
- 【MYSQL命令】查看日志是否开启及日志过期天数
show variables like 'log_%';show variables like '%expire_logs_days%'
- Sublime Text3.0的安装
Sublime Text是一款轻量级的易于使用的前端编写软件,个人比较推荐. 找到Sublime的官网,下载对应的版本后,点击安装.安装完成后需要下载相应的插件才能进行更加 有效率的开发工作.编写前端 ...
- 第三篇 Python关于mysql的API--pymysql模块, mysql事务
python关于mysql的API--pymysql模块 pymysql是Python中操作MySQL的模块,其使用方法和py2的MySQLdb几乎相同. 模块安装 pip install pymys ...
- Scrapy模拟登录GitHub
d: 进入D盘 scrapy startproject GitHub 创建项目 scrapy genspider github github.com 创建爬虫 编辑github.py: # -*- c ...
- Winrar去广告图文教程
一.前言 1.1 Winrar 解压缩工具 市场上有很多优秀的压缩工具,常用的有Winrar 和360 压缩工具.Winrar是免费压缩工具,特色是每次使用都会弹出广告.影响用户体验和工作效率,当然最 ...
- sqli-labs学习笔记 DAY3
DAY 3 sqli-labs lesson 6 同lesson 5,只是把单引号改为双引号 sqli-labs lesson 7 同lesson 5,只是把单引号后面加两个空格,使用Burpsuit ...
- 【C#】人脸识别 视频数据转图片数据
使用虹软人脸识别的开发过程中遇到了转换的问题 因为不会用C#直接打开摄像头,就只能用第三方dll.一开始用Aforge,后来发现有个问题,关闭摄像头老是陷入等待,所以抛弃了.前一阵子开始用封装了Ope ...