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 和有趣度 ...
随机推荐
- Vue修改
今天做的是一个Vue的修改操作: Vue主要是用来做视图来显示数据的,理解起来的话可能比较困难,学了好几天了,才刚摸到一点头绪,还是需要努力
- 【.NET】Swagger 允许接口重名
问题: Swagger Failed to load API definition. 相信用过swagger的小伙伴 一定经历过这样的错误,问题点很简单,是接口重名了. 我百度了一下,找不到答案. 谷 ...
- linux-minicom
q:只能发送不能接收 a:串口设置,硬件流控制=>NO
- mssql实现Split
create function Fun_Split( @SourceSql varchar ( 8000 ), @StrSeprate varchar ( 10 )) returns @temp ta ...
- GO语言http请求方法,可以携带请求头Header与cookie
1.目录 2.main.go package main import "fmt" import "demo/common/http" func main() { ...
- vuforia 打包IOS 第一次启动正常, 删掉过程重新启动初始化失败。
我使用的是2019.4.17版本,降级到2019.2.17问题解决
- mysql 中 insert 大量数据 避免时间戳相同 !!
时间函数 now() current_timestamp() 和 sysdate() CURRENT_TIMESTAMP and CURRENT_TIMESTAMP() are synonyms fo ...
- Swagger-ApiOperation-value属性
1.value属性设置 @ApiOperation(value="${province}.getUsers", notes="描述") Documentatio ...
- Linux开发——spi总线学习
1 spi总线协议简介 1.1 基本概念 SPI(Serial pe)
- k8s 关于pull image failed 问题
问题描述: Failed to pull image "nginx": rpc error: code = Unknown desc = failed to pul 解决办法: 1 ...