给定两个长度为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\)

link

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 提高组] 序列的更多相关文章

  1. luogu P6570 [NOI Online #3 提高组]优秀子序列 二进制 dp

    LINK:P6570 [NOI Online #3 提高组]优秀子序列 Online 2的T3 容易很多 不过出于某种原因(时间不太够 浪了 导致我连暴力的正解都没写. 容易想到 f[i][j]表示前 ...

  2. [NOI Online 2021 提高组] 积木小赛

    思路不说了. 想起来自己打比赛的时候,没睡好.随便写了个\(HASH\),模数开小一半分都没有. 然后学了\(SAM\),发现这个判重不就是个水题. \(SAM\)是字串tire的集合体. 随便\(d ...

  3. NOI ONLINE 提高组 序列 根据性质建图

    题目链接 https://www.luogu.com.cn/problem/P6185 题意 应该不难懂,跳过 分析 说实话第一眼看到这题的时候我有点懵,真不知道怎么做,不过一看数据,还好还好,暴力能 ...

  4. NOI Online #3 提高组 T1水壶 题解

    题目描述 有 n 个容量无穷大的水壶,它们从 1∼n 编号,初始时 i 号水壶中装有 Ai 单位的水. 你可以进行不超过 k 次操作,每次操作需要选择一个满足 1≤x≤n−1 的编号 x,然后把 x ...

  5. [NOI Online #2 提高组]涂色游戏 题解

    题目描述 你有 1020 个格子,它们从 0 开始编号,初始时所有格子都还未染色,现在你按如下规则对它们染色: 编号是 p1 倍数的格子(包括 0号格子,下同)染成红色. 编号是 p2 倍数的格子染成 ...

  6. NOI On Line 提高组题解

    (话说其实我想填的是去年CSP的坑...但是貌似有一道题我还不会写咕咕咕... 先写一下这一次的题解吧. T1:序列.题意省略. 两种操作.这种题要先分析部分分 给出了全部都是2操作的子任务. 发现A ...

  7. NOI Online #2 提高组 游戏

    没用二项式反演的菜比. 题目链接 Solution 非平局代表的树上祖先关系是比较好统计,(可以在处理一个点时,考虑用他去匹配他的子树中的东西)而平局的关系比较难统计.我们不妨求出至少 \(k\) 个 ...

  8. NOI Online #2 提高组 游记

    没 NOI Online 1 挂的惨就来写游记吧,不知道为啥 NOI Online 1 民间数据测得 60 分的 T1 最后爆零了... 昏昏沉沉的醒来,吃了早饭,等到 \(8:30\) 进入比赛网页 ...

  9. [NOI Online #1 提高组]

    A 首先从 \(t = 2\) 的特殊部分分出发. 不难发现这个操作是很不直观的,于是可以考虑对于每个操作 \((u, v)\) 在 \(u, v\) 之间连一条无向边. 显然连通块之间要分开考虑,对 ...

  10. CCF NOI Online 2021 提高组 T3 岛屿探险(CDQ 分治,Trie 树)

    题面 凇睦是一个喜欢探险的女孩子,这天她到一片海域上来探险了. 在这片海域上一共有 n 座岛屿排成一排,标号为 1, 2, 3, . . . , n.每座岛屿有两个权值,分别为劳累度 ai 和有趣度 ...

随机推荐

  1. 初次接触软构和git(使用eclipse)

    目录: 一.git和github 二.软件构造lab1常见问题(eclipse) 一.git和github 1. git的安装 百度git然后去官网安装即可,不会的可以去百度查一下. 2. git和g ...

  2. PLC入门笔记7

    梯形图与指令表的转换 后缀表达式 开头是MPS 结尾是MPP 中间就是MRD啦!!!! MPS 存入堆栈(将目前累加器的内容存入堆栈.(堆栈指针加一))将当前数据栈顶数据复制一份到辅助栈 栈深度+1 ...

  3. 格式化 ceph osd 盘报错stderr: wipefs: error: /dev/sdc: probing initialization failed: Device or resource busy

    1.格式化 ceph集群osd盘 出现设备繁忙,只能手动清空磁盘并重启 格式化:ceph-volume lvm zap /dev/sdc dd 手动清空磁盘:dd if=/dev/zero of=/d ...

  4. sqlserver substring 函数截取text格式文本格式乱码导致的定位错误的问题

    描述:使用 charindex 函数对 text 字段所要截取的内容下标读取例如:str(表字段名称-类型text)= <p>●123456</p> 截取 123 , inde ...

  5. 三级菜单python编码及高级编码

    # -*- coding: utf-8 -*- # @Time : 2020/7/31 0:13 # @Author : Breeze # @FileName: 三级菜单.py menu = { '北 ...

  6. Checkmarx

    1.概述 CheckMarx:是以色列的一家高科技软件公司,也是世界上最著名的源代码安全扫描软件CheckmarxCxSuite的生产商. Checkmarx CxEnterprise(Checkma ...

  7. 1008.Django模型基础03

    一.关系表的数据操作 关系表中的数据操作 查看数据库中的表结构 一对多表关系数据的添加: 1. 第一种方式就是跟之前一样,用传参的方法添加,需要注意的是外键的值必须是关联表中已存在的值: 2. 第二种 ...

  8. Eclipse's Import error and remove

    1.导入项目之前,请确认工作空间编码已设置为utf-8:window->Preferences->General->Wrokspace->Text file encoding- ...

  9. .NET实验三

    实验名称:实验三 Windows 应用程序开发 一. 实验目的 1. 掌握窗口控件的使用方法: 2. 掌握 Windows 的编程基础. 二. 实验要求   根据要求,编写 C#程序,并将程序代码和运 ...

  10. ORACLE数据库通过DBLINK连接另一个数据库

    ORACLE数据库通过DBLINK连接另一个数据库 亲测有效:create database link XXX --dblink名connect to 远程数据库用户名 identified by & ...