Stamp Rally
最大值最小,可以二分,然后并查集看能不能到z个点
但是询问过多,并且发现每次二分要加入的点并不是所有的m条边
于是就考虑整体二分
并查集的处理是重点:
对于一般的dfs分治树,
我们必然要在处理前面部分回溯来的时候,递归右子树之前,左子树并查集的信息必须保留。
但是还要删除当前层的部分并查集的合并操作。
如果直接路径压缩+暴力重构的话,到了后面,每次重构就是O(n)的了,直接N^2了。
为了支持删除,就考虑按秩合并。
合并成功的时候,用一个栈记录pair,然后删除的时候弹栈删除即可。相当于时光倒流
当然,之前的合并一定不能撤销的。
出错点:
1.l打成1海星。。。
2.如果当前区间没有决策位置的话,可以直接返回,但是这些[l,r]编号的边不能扔掉,必须直接加进去。
#include<bits/stdc++.h>
#define il inline
#define reg register int
#define numb (ch^'0')
using namespace std;
typedef long long ll;
il void rd(int &x){
char ch;bool fl=false;
while(!isdigit(ch=getchar()))(ch=='-')&&(fl=true);
for(x=numb;isdigit(ch=getchar());x=x*+numb);
(fl==true)&&(x=-x);
}
namespace Miracle{
const int N=1e5+;
const int M=1e5+;
struct node{
int x,y;
}e[M];
struct que{
int x1,x2,z;
int id,ans;
}q[M],b[M];
int fa[N];
int sz[N];
int op[N];
int n,m;
int fin(int x){
return fa[x]==x?x:fin(fa[x]);
}
pair<int,int>sta[N];
int top;
void merge(int x,int y,bool fl){
int k1=fin(x),k2=fin(y);
if(k1!=k2){
if(sz[k1]>sz[k2]) swap(k1,k2);
fa[k1]=k2;
sz[k2]+=sz[k1];
if(fl)sta[++top]=make_pair(k1,k2);
}
}
void dele(int x,int y){
fa[x]=x;
sz[y]-=sz[x];
}
void divi(int l,int r,int le,int ri){
//cout<<" l r "<<l<<" "<<r<<" : "<<le<<" and "<<ri<<endl;
if(l>r) return;
if(le>ri){
for(reg i=l;i<=r;++i){
merge(e[i].x,e[i].y,);
}
return;
}
if(l==r){
for(reg i=le;i<=ri;++i){
q[i].ans=l;
}
merge(e[l].x,e[l].y,);
return;
}
int mid=(l+r)>>;
for(reg i=l;i<=mid;++i){
merge(e[i].x,e[i].y,);
}
//cout<<" mid "<<mid<<endl;
int pre=le-,bac=ri+;
for(reg i=le;i<=ri;++i){
int k1=fin(q[i].x1),k2=fin(q[i].x2);
int tmp=;
if(k1!=k2){
tmp=sz[k1]+sz[k2];
}else{
tmp=sz[k1];
}
if(tmp>=q[i].z) b[++pre]=q[i];
else b[--bac]=q[i];
}
for(reg i=le;i<=ri;++i){
q[i]=b[i];
}
//cout<<" pre "<<pre<<" bac "<<bac<<" top "<<top<<endl;
//if(top){
while(top){
dele(sta[top].first,sta[top].second);
--top;
}
//}
divi(l,mid,le,pre);
divi(mid+,r,bac,ri);
}
int main(){
rd(n);rd(m);
for(reg i=;i<=m;++i){
rd(e[i].x);rd(e[i].y);
}
int que;
rd(que);
for(reg i=;i<=que;++i){
rd(q[i].x1);rd(q[i].x2);rd(q[i].z);
q[i].id=i;
}
for(reg i=;i<=n;++i){
fa[i]=i;sz[i]=;//;dep[i]=1;
}
divi(,m,,que);
for(reg i=;i<=que;++i){
op[q[i].id]=q[i].ans;
}
for(reg i=;i<=que;++i){
printf("%d\n",op[i]);
}
return ;
} }
signed main(){
// freopen("data.in","r",stdin);
// freopen("my.out","w",stdout);
Miracle::main();
return ;
} /*
Author: *Miracle*
Date: 2018/12/18 8:37:44
*/
还有一种:
你不是暴力重构会TLE吗?但是我一共就需要循环logn次O(m)地把并查集加入
考虑逐层处理
因为对于整体二分,bfs和dfs的顺序都没有问题。
所以bfs处理整体二分,这样,加入就直接加入了,只要暴力重构O(logn)次。
bfs+路径压缩,理论上可以更快一些。
Stamp Rally的更多相关文章
- AtCoder Grand Contest 002 D - Stamp Rally
Description We have an undirected graph with N vertices and M edges. The vertices are numbered 1 thr ...
- [AGC002D] Stamp Rally
确实有想到重构树,不过没有继续下去的思路. 可能是对重构树的性质不太懂. 这种题目我们可以二分答案,考虑怎么\(check\)呢,整体二分+并查集,建出重构树,找去第一个小于这个数的方点,查询他的子树 ...
- 【做题】agc002D - Stamp Rally——整体二分的技巧
题意:给出一个无向连通图,有\(n\)个顶点,\(m\)条边.有\(q\)次询问,每次给出\(x,y,z\),最小化从\(x\)和\(y\)开始,总计访问\(z\)个顶点(一个顶点只计算一次),经过的 ...
- [AGC002D] Stamp Rally 整体二分+并查集
Description 给你一个n个点m个条边构成的简单无向连通图,有Q组询问,每次询问从两个点x,y走出两条路径,使这两条路径覆盖z个点,求得一种方案使得路径上经过的变的最大编号最小. Input ...
- [AGC002D] Stamp Rally (并查集+整体二分)
Description 给你一个n个点m个条边构成的简单无向连通图,有Q组询问,每次询问从两个点x,y走出两条路径,使这两条路径覆盖z个点,求得一种方案使得路径上经过的变的最大编号最小. Input ...
- 【agc002d】Stamp Rally
题目大意 无向图中,每次询问从x和y分别出发,一共经过z个点,使需要走过编号最大的边最小. 解题思路 对于暴力,我们对于每个询问二分答案ans,将1~ans的边加入,用并查集维护,如果x和y在同一个并 ...
- AtCoder Grand Contest 002
AtCoder Grand Contest 002 A - Range Product 翻译 告诉你\(a,b\),求\(\prod_{i=a}^b i\)是正数还是负数还是零. 题解 什么鬼玩意. ...
- RE:从零开始的AGC被虐(到)生活(不能自理)
RE:从零开始的AGC被虐(到)生活(不能自理) 「一直注视着你,似近似远,总是触碰不到.」 --来自风平浪静的明天 AtCoder Grand Contest 001 B: Mysterious L ...
- AtCoder Grand Contest
一句话题解 QwQ主要是因为这篇文章写的有点长……有时候要找某一个题可能不是很好找,所以写了这个东西. 具体的题意.题解和代码可以再往下翻._(:з」∠)_ AGC 001 C:枚举中点/中边. D: ...
随机推荐
- 关于jQuery Form Plugin使用心得
吐槽一下先 好久没开发了,今天遇到一个客户form提交的问题,想把form提交从同步变成ajax的异步方式,在网页接受返回来的数据,使用的是jquery from插件,于是网上搜了一圈,博客园,csd ...
- 如何通过阿里云APP进行域名备案?阿里云备案流程需要多久?
如何通过阿里云APP进行域名备案? 1.准备备案材料(很多初次使用阿里云APP进行备案的同学会问备案需要准备哪些资料,不二版本下面就给大家一一列举出来) 个人备案需要材料: ⑴<用户网站备案授权 ...
- Leetcode_6. Zigzag convertion
6. Zigzag convertion 对输入的字符串做锯齿形变换,并输出新的字符串,所谓zigzag变化如下图所示. 将"ABCDEFGHIJKL"做4行的锯齿变换,新的字符串 ...
- dvwa——sql手动注入和sqlmap自动注入
手动注入 low: 源码: <?php if( isset( $_REQUEST[ 'Submit' ] ) ) { // Get input $id = $_REQUEST[ 'id' ]; ...
- plsql 不修改tnsnames.ora文件
PLSQL 不修改tnsname直接连数据库的方式在PLSQL的Database中直接输入192.168.1.6:1521/VP.其中192.168.1.6为数据库的IP:1521为数据库端口:VP为 ...
- "prefs:root" or "App-Prefs:root"
iOS 苹果审核也是看心情的吗?已经上线几个版本了,新版本提交审核居然被查出来了! Guideline 2.5.1 - Performance - Software Requirements Your ...
- 最小费用最大流模板(POJ 2135-Farm Tour)
最近正好需要用到最小费用最大流,所以网上就找了这方面的代码,动手写了写,先在博客里存一下~ 代码的题目是POJ2135-Farm Tour 需要了解算法思想的,可以参考下面一篇文章,个人觉得有最大流基 ...
- 渐入OO课的深处,探索多线程的秘密——OO第二次博客总结
一次又一次的挑战,一次又一次全新的知识,我来到了多线程的面前 第五次作业 1.度量分析 >第五次作业由于很大程度上调用的是前两次电梯的一些代码,所以存在的问题与前几次也十分相似.同时由于第一次使 ...
- 20162319 实验二 Java面对对象程序设计 实验报告
实验二 Java面向对象程序设计 实验内容 1.初步掌握单元测试和TDD 2.理解并掌握面向对象三要素:封装.继承.多态 3.初步掌握UML建模 4.熟悉S.O.L.I.D原则 5.了解设计模式 实验 ...
- 剑指offer:旋转数组的最小数字
题目描述: 把一个数组最开始的若干个元素搬到数组的末尾,我们称之为数组的旋转. 输入一个非减排序的数组的一个旋转,输出旋转数组的最小元素. 例如数组{3,4,5,1,2}为{1,2,3,4,5}的一个 ...