正题

题目链接:https://www.luogu.com.cn/problem/CF603E


题目大意

开始时有nnn个点,没有边。

依次加入mmm条带权的边,每次加入后询问是否存在一个边集,满足每个点的度数均为奇数,求使得这个边集的最大权值最小。

1≤n≤105,1≤m≤3×1051\leq n\leq 10^5,1\leq m\leq 3\times 10^51≤n≤105,1≤m≤3×105


解题思路

首先考虑存在这个边集的条件,可以证明存在满足条件的边集的充要条件是联通块的大小都是偶数。
必要性:对于一个联通块,因为每条边都会贡献偶数个度数,而如果这个连通块是奇数个点,那么如果合法的总度数就是 奇数×奇数=奇数 ,显然不可能是偶数,所以不存在这种情况。
充分性:如果存在一个点的度数为奇数,那么这个联通快里也至少有一个点的度数是奇数,我们顺路删掉这两个点路径上的边就可以调整到合法情况。

而我们能连边就连边肯定是最优的,因为不存在一种连边会使得奇数连通块数变多。

然后考虑用CDQ分治解决这题,注意到答案肯定是单调不升的,我们的流程是记录目前区间[l,r][l,r][l,r]的答案区间{L,R}\{L,R\}{L,R}。

先计算出ansmidans_{mid}ansmid​,那么此时我们就可以分为[l,mid−1]{ansmid,R}[l,mid-1]\{ans_{mid},R\}[l,mid−1]{ansmid​,R}和[mid+1,r]{L,ansmid}[mid+1,r]\{L,ans_{mid}\}[mid+1,r]{L,ansmid​}

此时两个区间都被分开,这提示我们暴力枚举这些区间就是正常分治的复杂度。

那么做法就很显然了,我们算出ansmidans_{mid}ansmid​后左右两边递归处理,用可撤销并查集处理。

时间复杂度:O(mlog⁡mlog⁡n)O(m\log m\log n)O(mlogmlogn)


code

#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
const int N=3e5+10;
struct node{int x,y,w,id;
}a[N],b[N];
struct clnode{int x,y,siz,dep;
}cl[N];
int n,m,sum,clt,fa[N],siz[N],dep[N];
int ans[N],rk[N];
int find(int x)
{return (fa[x]==x)?x:find(fa[x]);}
void unionn(int x,int y){x=find(x);y=find(y);if(x==y)return;if(dep[x]>dep[y])swap(x,y);cl[++clt]=(clnode){x,y,siz[y],dep[y]};sum-=(siz[x]&1)&(siz[y]&1);fa[x]=y;siz[y]+=siz[x];dep[y]=max(dep[y],dep[x]+1);
}
void clearto(int d){while(clt>d){int x=cl[clt].x,y=cl[clt].y;siz[y]=cl[clt].siz;dep[y]=cl[clt].dep;sum+=(siz[x]&1)&(siz[y]&1);fa[x]=x;clt--;}return;
}
void cdq(int l,int r,int L,int R){if(l>r)return;int mid=(l+r)>>1,now=clt;for(int i=l;i<=mid;i++)if(rk[i]<L)unionn(a[i].x,a[i].y);int mow=clt;for(int i=L;i<=R;i++){if(b[i].id<=mid)unionn(b[i].x,b[i].y);if(!sum){ans[mid]=i;break;}}if(!ans[mid]){clearto(mow);cdq(mid+1,r,L,R);return;}clearto(mow);cdq(mid+1,r,L,ans[mid]);clearto(now);for(int i=L;i<ans[mid];i++)if(b[i].id<l)unionn(b[i].x,b[i].y);cdq(l,mid-1,ans[mid],R);clearto(now);return;
}
bool cmp(node x,node y)
{return x.w<y.w;}
int main()
{scanf("%d%d",&n,&m);sum=n/2;if(n&1){for(int i=1;i<=m;i++)puts("-1");return 0;}for(int i=1;i<=n;i++)fa[i]=i,siz[i]=1;for(int i=1;i<=m;i++){scanf("%d%d%d",&a[i].x,&a[i].y,&a[i].w);a[i].id=i;b[i]=a[i];}sort(b+1,b+1+m,cmp);for(int i=1;i<=m;i++)rk[b[i].id]=i;cdq(1,m,1,m);for(int i=1;i<=m;i++)if(!ans[i])puts("-1");else printf("%d\n",b[ans[i]].w);return 0;
}

CF603E-Pastoral Oddities【CDQ分治,可撤销并查集】相关推荐

  1. 线段树分治 ---- F. Extending Set of Points(线段树分治 + 可撤销并查集)

    题目链接 题目大意: 你有个点集合SSS,每次往集合里面加点或者删点(如果要加的点出现过),如果(x1,y1),(x2,y1),(x1,y2),(x2,y2)(x1,y1),(x2,y1),(x1,y ...

  2. 【CF603E】Pastoral Oddities cdq分治+并查集

    [CF603E]Pastoral Oddities 题意:有n个点,依次加入m条边权为$l_i$的无向边,每次加入后询问:当前图是否存在一个生成子图,满足所有点的度数都是奇数.如果有,输出这个生成子图 ...

  3. [WC2005]双面棋盘,洛谷P4121,线段树分治+可撤销并查集

    正题 这题主要是来练手的,因为没写过可撤销的并查集,大概就是把每一个格子看成一个点,然后格子直接的边有很多的出现区间,把这些出现区间和对应的颜色打到线段树上,然后用可撤销的并查集来维护就可以了. #i ...

  4. 线段树分治 ---- CF1217F - Forced Online Queries Problem(假离线 可撤销并查集 + 线段树分治)详解

    题目链接 题目大意 解题思路: 我一开始想到可以用可撤销并查集去维护这种删边加边的操作,但是有个缺点是每次撤销都有把后面的边全部撤销复度是O(n2)O(n^2)O(n2) 首先我们考虑这种动态加边删边 ...

  5. 【BZOJ4025】二分图(可撤销并查集+线段树分治)

    题目: BZOJ4025 分析: 定理:一个图是二分图的充要条件是不存在奇环. 先考虑一个弱化的问题:保证所有边出现的时间段不会交叉,只会包含或相离. 还是不会?再考虑一个更弱化的问题:边只会出现不会 ...

  6. 【Codeforces576E_CF576E】Painting Edges(可撤销并查集+线段树分治)

    题目 CF576E 分析: 从前天早上肝到明天早上qwq其实颓了一上午MC ,自己瞎yy然后1A,写篇博客庆祝一下. 首先做这题之前推荐一道很相似的题:[BZOJ4025]二分图(可撤销并查集+线段树 ...

  7. 洛谷P7518:宝石(倍增、可撤销并查集)

    解析 算法一 定义 upx,kup_{x,k}upx,k​ 为节点 xxx 从自己的颜色所在位置在返祖链上往后跳 2k2^k2k 个颜色到达的节点. 可以像倍增一样的求解. 这样对于一次询问 (s,t ...

  8. BZOJ4358: permu(带撤销并查集 不删除莫队)

    题意 题目链接 Sol 感觉自己已经老的爬不动了.. 想了一会儿,大概用个不删除莫队+带撤销并查集就能搞了吧,\(n \sqrt{n} logn\)应该卡的过去 不过不删除莫队咋写来着?....跑去学 ...

  9. codeforces 892E(离散化+可撤销并查集)

    题意 给出一个n个点m条边的无向联通图(n,m<=5e5),有q(q<=5e5)个询问 每个询问询问一个边集{Ei},回答这些边能否在同一个最小生成树中 分析 要知道一个性质,就是权值不同 ...

最新文章

  1. linux目录档案权限详解,五、Linux的档案权限与目录配置
  2. 《北妹》:中国七零后作家的一次火山喷发(答记者问)
  3. hdu 2026 首字母变大写
  4. 福大软工1816 · 第二次作业 - 个人项目
  5. 【自然框架】——重开在线演示
  6. Qt4_有注解的地图程序
  7. POJ 3576 Language Recognition
  8. Java 8 中的 Map 骚操作,学习下
  9. 今天第72个儿童节,程序猿“童”样精彩~
  10. [外星与文明]外星人的离开对地球有什么影响?
  11. 动态爬虫之手机版QQ空间登录
  12. 湖州南浔张静江:“满堂花醉三千客,一剑霜寒四十州”
  13. C#开发ActiveX控件
  14. 《不花钱学法语》--18个网站,强化法语六力
  15. Spring aop报错:com.sun.proxy.$Proxyxxx cannot be cast to yyy
  16. android javapoet 翻译
  17. TMC6300-LA:微型BLDC/PMSM驱动
  18. 安装SQL Server 2000时“以前的某个程序安装已在安装计算机上创建挂起的文件操作。运行安装程序之前必须重新启动计算机”错误的排除
  19. 2020联发科技笔试面试经验
  20. 第三天 入口文件index.php 01

热门文章

  1. doxygen如何生成JAVA文档_有用Doxygen生成文档的吗?发一篇Doxygen的使用文档给大家,从网上搜来的。...
  2. 最近有粉丝向我请教Java泛型,于是重温了一下,希望学弟面试顺利
  3. html assign无效,Object.assign的一些用法
  4. matlab编程数字信号,MATLAB--数字信号实验.doc
  5. 2020邮箱账号密码大全_通知 | 复旦大学2020年春季学期研究生选课FAQ
  6. java get请求简洁,java 实现 HTTP请求(GET、POST)的方法
  7. 11尺寸长宽 iphone_新手必知LED显示屏尺寸规格及计算方法
  8. html怎么防止表单重复提交,js防止表单重复提交的解决方法
  9. northstar机器人编程_《机器人构建实战》——导读
  10. leetcode145. 二叉树的后序遍历