P6185 [NOI Online #1 提高组] 序列
给定两个长度为n的序列\(A\),\(B\)。
有m个可用的操作\((t_i,u_i,v_i)\)。
\(t\)代表操作类型。
当\(t=1\)时,表示能够将\(A_{u_i}\)和\(A_{v_i}\)同时\(+1\);
当\(t=2\)时,表示能够将\(A_{u_i}\)和\(A_{v_i}\)其中一者\(+1\),另者\(-1\);
所有操作使用顺序和次数不限,问能否使得\(A\)变成\(B\)
sol
先将类型\(2\)的边连接。我们会得到一些连通块。
由于连通分量中任意两点都存在路径,所以对于任意\((u,v)\)我们可以通过\((u,v)\)这条路径使得\(A_u+1\),\(A_v-1\)。
由此易得对于一个连通分量,我们可以在不改变整个连通分量点权和的前提下任意改变其中节点的值。
这部分就可以拿并查集缩点掉了(
缩点后将类型\(1\)的边连接。
(1)此时的图如果是二分图,那么显然,我们可以在二分图两侧增量相同的前提下任意改变节点的值。
(2)如果不是二分图,也就是存在奇环,显然我们可以通过【一个节点+这个节点到奇环的路径+这个奇环】这样一个组合来使得这个节点 \(\pm\) 一个偶数。
由此易得,我们可以在点权和增量为偶数的前提下任意改变其中节点的值。
然后写法就很显然了()
先连类型\(2\)的边,用并查集染色缩点并计算缩点后点权;再连\(1\)边。对于新图的每个连通分量,用黑白染色判定是否为二分图,染色过程分别统计黑白增量\(wb_i-wa_i\)的和。如果是二分图就判断黑白增量是否相等,如果不是就判断(伪)黑白增量(即总增量)的总和是否为偶数
我不知道负数mod会发生什么()所以判断增量奇偶的时候+了个巨大偶数
第一次编译运行没过样例 + 第一次提交 WA 55pts 错在同个地方,就是并查集染色后建边的地方,前者是因为没按颜色建边而按点编号建边,后者是因为没建双向边
没因为多测初始化的问题挂掉,还好...
但虽然整体蛮顺利,完成代码本身还是花了将近1h的样子。太慢了(sad(虽然我一边写还在反复尝试严谨证,不过最后一写总结就清楚了
#include <algorithm>
#include <iostream>
#include <cstring>
#include <cstdio>
#include <cmath>
#define MAXN (int)(1e5+233)
#define MAXM (int)(1e5+233)
#define MAXAB (int)(1e9+233)
using namespace std;
int n,m;
int a[MAXN],b[MAXN];
long long wa[MAXN],wb[MAXN];
long long sum1,sum2;
struct qwq
{
int nex,to;
}e[MAXM<<1];
int h[MAXN],tot=0;
struct edgee
{
int u,v;
}E[MAXM];
int Ecnt=0;
inline void add(int x,int y)
{
e[++tot].to=y;
e[tot].nex=h[x];
h[x]=tot;
}
int fa[MAXN];
int found(int x)
{
if (fa[x]==x) return x;
return fa[x]=found(fa[x]);
}
int col[MAXN],c_count=0;
int typ[MAXN];
inline void INIT() { for (int i=1;i<=n;i++) fa[i]=i,h[i]=0,typ[i]=0,wa[i]=0,wb[i]=0,col[i]=0; tot=0; c_count=0; Ecnt=0; }
bool dfs_bina(int x)
{
if (typ[x]==1) sum1+=(wb[x]-wa[x]);
else if (typ[x]==2) sum2+=(wb[x]-wa[x]);
bool wnw=true;
for (int i=h[x],y;i;i=e[i].nex)
{
y=e[i].to;
//printf("Edge: %d %d\n",x,y);
if (!typ[y])
{
typ[y]=3-typ[x];//rem INIT typ[x]
if (!dfs_bina(y)) wnw=false;
}
else if (typ[y]==typ[x]) wnw=false;
}
return wnw;
}
inline bool sol2(int x)
{
sum1=sum2=0;
typ[x]=1;
bool wnw=dfs_bina(x);
// printf(":::%d %lld %lld\n",wnw,sum1,sum2);
if (wnw)
{
if (sum1==sum2) return true;
else return false;
}
else
{
if ((sum1+sum2+1000000000)&1) return false;
else return true;
}
}
inline void sol()
{
scanf("%d%d",&n,&m);
INIT();
for (int i=1;i<=n;i++) scanf("%d",&a[i]);
for (int j=1;j<=n;j++) scanf("%d",&b[j]);
for (int i=1,t,u,v,fu,fv;i<=m;i++)
{
scanf("%d%d%d",&t,&u,&v);
if (t==1) E[++Ecnt]=(edgee){u,v};
else
{
fu=found(u); fv=found(v);
if (fu!=fv) fa[fu]=fv;
}
}
for (int i=1;i<=n;i++)
if (fa[i]==i) col[i]=++c_count;
for (int i=1;i<=n;i++)
col[i]=col[found(i)],wa[col[i]]+=a[i],wb[col[i]]+=b[i];
for (int i=1;i<=Ecnt;i++)
// if (col[E[i].u]!=col[E[i].v])
add(col[E[i].u],col[E[i].v]),add(col[E[i].v],col[E[i].u]);
bool answer=1;
for (int i=1;i<=c_count;i++)
if (!typ[i]) answer&=sol2(i);
if (answer) printf("YES\n");
else printf("NO\n");
return;
}
int main()
{
int T;
scanf("%d",&T);
while (T--) sol();
return 0;
}
P6185 [NOI Online #1 提高组] 序列的更多相关文章
- luogu P6570 [NOI Online #3 提高组]优秀子序列 二进制 dp
LINK:P6570 [NOI Online #3 提高组]优秀子序列 Online 2的T3 容易很多 不过出于某种原因(时间不太够 浪了 导致我连暴力的正解都没写. 容易想到 f[i][j]表示前 ...
- [NOI Online 2021 提高组] 积木小赛
思路不说了. 想起来自己打比赛的时候,没睡好.随便写了个\(HASH\),模数开小一半分都没有. 然后学了\(SAM\),发现这个判重不就是个水题. \(SAM\)是字串tire的集合体. 随便\(d ...
- NOI ONLINE 提高组 序列 根据性质建图
题目链接 https://www.luogu.com.cn/problem/P6185 题意 应该不难懂,跳过 分析 说实话第一眼看到这题的时候我有点懵,真不知道怎么做,不过一看数据,还好还好,暴力能 ...
- NOI Online #3 提高组 T1水壶 题解
题目描述 有 n 个容量无穷大的水壶,它们从 1∼n 编号,初始时 i 号水壶中装有 Ai 单位的水. 你可以进行不超过 k 次操作,每次操作需要选择一个满足 1≤x≤n−1 的编号 x,然后把 x ...
- [NOI Online #2 提高组]涂色游戏 题解
题目描述 你有 1020 个格子,它们从 0 开始编号,初始时所有格子都还未染色,现在你按如下规则对它们染色: 编号是 p1 倍数的格子(包括 0号格子,下同)染成红色. 编号是 p2 倍数的格子染成 ...
- NOI On Line 提高组题解
(话说其实我想填的是去年CSP的坑...但是貌似有一道题我还不会写咕咕咕... 先写一下这一次的题解吧. T1:序列.题意省略. 两种操作.这种题要先分析部分分 给出了全部都是2操作的子任务. 发现A ...
- NOI Online #2 提高组 游戏
没用二项式反演的菜比. 题目链接 Solution 非平局代表的树上祖先关系是比较好统计,(可以在处理一个点时,考虑用他去匹配他的子树中的东西)而平局的关系比较难统计.我们不妨求出至少 \(k\) 个 ...
- NOI Online #2 提高组 游记
没 NOI Online 1 挂的惨就来写游记吧,不知道为啥 NOI Online 1 民间数据测得 60 分的 T1 最后爆零了... 昏昏沉沉的醒来,吃了早饭,等到 \(8:30\) 进入比赛网页 ...
- [NOI Online #1 提高组]
A 首先从 \(t = 2\) 的特殊部分分出发. 不难发现这个操作是很不直观的,于是可以考虑对于每个操作 \((u, v)\) 在 \(u, v\) 之间连一条无向边. 显然连通块之间要分开考虑,对 ...
- CCF NOI Online 2021 提高组 T3 岛屿探险(CDQ 分治,Trie 树)
题面 凇睦是一个喜欢探险的女孩子,这天她到一片海域上来探险了. 在这片海域上一共有 n 座岛屿排成一排,标号为 1, 2, 3, . . . , n.每座岛屿有两个权值,分别为劳累度 ai 和有趣度 ...
随机推荐
- Latex Algorithm 语法错误导致无法编译
遇到了几种情况: 1. for 循环没加{} 2. $\textbf{T_i}$, 想要加粗T,但是把i也扩进去了,latex就不懂了,于是一直recompile不出来说超时什么什么的,把i放到外面就 ...
- Gabor滤波(个人学习)
Gabor滤波 1.优点 Gabor小波与人类视觉系统中简单细胞的视觉刺激响应非常相似.在提取目标的局部空间和频率与信息方面具有良好的特性. 对于图像的边缘敏感,能够提供良好的方向选择和尺度选择.因此 ...
- Monterey 12.3 I225-V有线网卡导致死机或无法使用问题
问题:升级Monterey12.3后启动到桌面死机 解决方法: 1.关闭/去掉所有有线网卡驱动.补丁.网卡设备ID注入: 2.启动命令中加入:dk.e1000=0: 3.启动不死机后,进入网络设置,手 ...
- linux 系统安装配置jdk + mysql + redis (离线状态)
系统版本:centos7.7 环境搭建(离线状态) 安装java环境 安装配置mysql数据库 安装配置redis数据库 安装java环境 jdk版本:jdk-8u5-linux-x64.rpm ...
- HTML基础知识学习
一.HTML概述 1.系统结构: ①.B/S架构 Browser Server(浏览器/服务器的交互形式.) Browser支持哪些语言:HTML CSS Javascript S是服务器端Serve ...
- (三).JavaScript的分支结构和循环结构
1. 分支结构 1.1 分支语句之单分支 ①.语法: if(值,如果不是布尔值会强制转换成布尔值) { 代码块; } ②.案例: // 案例:如果a变量的值加键盘上输入的数大于100,就打印我爱你二狗 ...
- 【BFS】算法模板与思路
1.BFS算法的基础理论是什么? BFS算法名叫宽度优先搜索,虽然我能理解深度优先搜索,但我却不是很能理解宽度优先搜索. 一个很关键的点在于:宽度优先搜索是一个迭代的算法,不是递归的算法. 与DFS之 ...
- Django数据迁移介绍
1.简介 迁移是 Django 将你对模型的修改(例如增加一个字段,删除一个模型)应用至数据库表结构对方式 2.基本命令 python manage.py migrate---负责应用和撤销迁移 py ...
- 后端006_登录之后返回Token
现在开始我们就可以写登录相关的东西了.首先登录相关的流程是这样的,前端输入用户和密码传给后端,后端判断用户名和密码是否正确,若正确,则生成JWT令牌,若不正确,则需要让前端重新输入,前端如果拿到了JW ...
- 【LuckyFrame研究】下载安装包
下载安装包,可以快速部署 百度网盘链接: https://pan.baidu.com/s/1SNUhzoKFgH2TRQN2Rx711A 提取码: u845 服务端压缩包 V3.X版本:Lucky ...