传送门

子任务 $4$ 告诉我们可以离线搞带权并查集

从大到小枚举询问,从大到小连边

如果没有修改操作就可以过了

但是有修改,考虑最暴力的暴力,搞可撤销并查集

同样先离线,从大到小处理询问时,按原边权从大到小枚举到一条边时,如果他一直都没有修改,那么直接加入并查集

如果有修改那先不要加,枚举所有修改看看当前时间它的边权,然后如果它的边权大于等于询问权值,才加入并查集

最后还得撤销有修改的边,因为它们修改后的边权不满足从大到小

这样复杂度显然很高,因为我们每次都要撤销一堆操作,还要枚举所有修改

考虑分块,按操作数量分块

对于每个块,时间在它之前的所有操作肯定已经做完了,那么枚举修改时就少了很多枚举

同理撤销的时候也只要撤销块内的操作,每个块做完直接把相应边权更改重新排序(归并排序可以做得比较快,代码里用 $sort$ )

然后复杂度就很可行了

#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cstring>
#include<cmath>
#include<vector>
using namespace std;
typedef long long ll;
inline int read()
{
int x=,f=; char ch=getchar();
while(ch<''||ch>'') { if(ch=='-') f=-; ch=getchar(); }
while(ch>=''&&ch<='') { x=(x<<)+(x<<)+(ch^); ch=getchar(); }
return x*f;
}
const int N=5e5+,SIZE=;//块大小自己试几次
int n,m,T;
struct edge{//边
int u,v,w,id;
edge (int a=,int b=,int c=,int d=) { u=a,v=b,w=c,id=d; }
inline bool operator < (const edge &tmp) const {
return w>tmp.w;
}
}E[N];
struct dat{//操作
int x,w,id;
dat (int a=,int b=,int c=) { x=a,w=b,id=c; }
inline bool operator < (const dat &tmp) const {
return w>tmp.w;
}
};
vector <dat> Q,C;//Q存询问,C存操作
int fa[N],sz[N],st[N],Top;//待撤销并查集,st维护操作序列
int find(int x) { return x==fa[x] ? x : find(fa[x]); }
inline void merge(int x,int y)//启发式合并
{
int u=find(x),v=find(y); if(u==v) return;
if(sz[u]<sz[v]) swap(u,v);
fa[v]=u; sz[u]+=sz[v]; st[++Top]=v;
}
int ans[N],mx[N],id[N];//mx[i]是当前编号为i的边的权值,id[i]是编号为i的边当前的位置
void solve()
{
sort(E+,E+m+);//每次都sort
for(int i=;i<=m;i++) mx[i]=,id[ E[i].id ]=i; Top=;
for(int i=;i<=n;i++) sz[i]=,fa[i]=i;
for(dat x : C) mx[x.x]=-;//初始化,有修改的边先赋成-1
sort(Q.begin(),Q.end()); int j=,las,p;//把询问排序
for(dat q : Q)//从大到小枚举询问
{
for(;E[j].w>=q.w;j++) if(!mx[ E[j].id ]) merge(E[j].u,E[j].v);//如果此边没有修改可以直接加入并查集
las=Top;
for(dat x : C) mx[x.x]=E[ id[x.x] ].w;//一开始先赋成原本值
for(dat x : C) if(x.id<q.id) mx[x.x]=x.w;//有修改且时间比询问早就修改
//这时更改时间在后面的边的mx也更新好了
for(dat x : C) if(mx[x.x]>=q.w) merge(E[ id[x.x] ].u,E[ id[x.x] ].v);//如果边权较大才加入并查集
ans[q.id]=sz[ find(q.x) ];//更新答案
while(Top>las) p=st[Top--],sz[fa[p]]-=sz[p],fa[p]=p;//撤回
}
for(dat x : C) E[ id[x.x] ].w=x.w;//一个块搞完把相应边权更改改
C.clear(); Q.clear();//记得清空
}
int main()
{
n=read(),m=read();
for(int i=;i<=m;i++) E[i].u=read(),E[i].v=read(),E[i].w=read(),E[i].id=i;
T=read(); int opt,cnt=; dat a;
for(int i=;i<=T;i++)
{
opt=read(); a.x=read(); a.w=read(); a.id=i;
opt== ? C.push_back(a) : Q.push_back(a);
cnt++; if(cnt==SIZE) solve(),cnt=;
}
if(cnt) solve();
for(int i=;i<=T;i++) if(ans[i]) printf("%d\n",ans[i]);
return ;
}

P5443 [APIO2019]桥梁的更多相关文章

  1. P5443 [APIO2019]桥梁 [分块+并查集]

    分块+并查集,大板子,没了. 并查集不路径压缩,可撤销,然后暴力删除 这样对于每个块都是独立的,所以直接搞就行了. 然后块内修改操作搞掉,就是单独的了 // powered by c++11 // b ...

  2. 【LOJ#3145】[APIO2019]桥梁(分块,并查集)

    [LOJ#3145][APIO2019]桥梁(分块,并查集) 题面 LOJ 题解 因为某个\(\text{subtask}\)没判\(n=1\)的情况导致我自闭了很久的题目... 如果没有修改操作,可 ...

  3. 题解 洛谷 P5443 【[APIO2019]桥梁】

    考虑若只有查询操作,那么就可以构造\(Kruskal\)重构树,然后在线询问了,也可以更简单的把询问离线,把询问和边都按权值从大到小排序,然后双指针依次加入对于当前询问合法的边,用并查集维护每个点的答 ...

  4. 题解-APIO2019桥梁

    problem \(\mathrm {loj-3145}\) 题意概要:给定一张 \(n\) 点 \(m\) 边的无向图,边有边权,共 \(q\) 次操作,每次会将第 \(x\) 条边的权值改为 \( ...

  5. APIO2019简要题解

    Luogu P5444 [APIO2019]奇怪装置 看到这种题,我们肯定会想到\((x,y)\)一定有循环 我们要找到循环节的长度 推一下发现\(x\)的循环节长为\(\frac{AB}{B+1}\ ...

  6. 【APIO2019】桥梁(询问分块)

    Description 给定一张 \(n\) 个点,\(m\) 条边的无向图,边 \(i\) 的权值为 \(d_i\).现有 \(q\) 次操作,第 \(j\) 个操作有两种模式: \(1\ b_j\ ...

  7. [APIO2019] [LOJ 3145] 桥梁(分块+并查集)(有详细注释)

    [APIO2019] [LOJ 3145] 桥梁(分块+并查集)(有详细注释) 题面 略 分析 考试的时候就感觉子任务4是突破口,结果却写了个Kruskal重构树,然后一直想怎么在线用数据结构维护 实 ...

  8. APIO2019 题解

    APIO2019 题解 T1 奇怪装置 题目传送门 https://loj.ac/problem/3144 题解 很容易发现,这个东西一定会形成一个环.我们只需要求出环的长度就解决了一切问题. 设环的 ...

  9. 游戏测评-桥梁建造系Poly Bridge破力桥?游戏测评

    最近在b站看到了谜之声的视频:大家来造桥吧! 实在是太搞笑了,看到是一款新出不久还未正式发行的游戏,兴致一来便入手玩了玩.顺手也就写下了这篇测评. POLY BRIDGE 对这个游戏名怎么起个有趣的中 ...

随机推荐

  1. 【01】Python 环境变量、条件判断、循环、基本运算符

    1 环境变量 1.1 Windows下环境变量 系统变量Path中要加入Python安装路径: C:\xxxx\Python36;C:\xxxx\Python36\Scripts; 2 条件判断 2. ...

  2. 【GDOI2016模拟3.9】暴走的图灵机

    题目 分析 我们发现当两个字符串合并时,a0.a1表示左右两个字符串中有多少个T,C表示合并处新增的T的个数,那么 a0=a1 a1=a0+a1+C 令s0和s1表示左右手两个字符串,那么每一次操作后 ...

  3. 【leetcode】491. Increasing Subsequences

    题目如下: 解题思路:这题把我折腾了很久,一直没找到很合适的方法,主要是因为有重复的数字导致结果会有重复.最后尝试用字典记录满足条件的序列,保证不重复,居然Accept了. 代码如下: class S ...

  4. new Date(str)返回 Invalid date问题

    var date=new Date($("input[name='mettingTime']").val().replace(/-/g, "/")); var ...

  5. 在Python中,如何将一个字符串数组转换成整型数组

    https://blog.csdn.net/xiangchengguan/article/details/78987041 arr = ['] arr = list(map(int,arr)) pri ...

  6. 「HNOI2016」矿区

    https://loj.ac/problem/2052 题解 平面图转对偶图.. 首先我们转的话需要给所有的平面标号,然后找到每条边看看他们隔开了哪两个平面. 做法就是对每个点维护它的所有排好序的出边 ...

  7. fedora18 [linux]Error: failure: repodata/repomd.xml from fedora: [Errno 256] No more mirrors to try.

    在使用fedora17 系统的yum源的时候出现了如下错误: Error: failure: repodata/repomd.xml from fedora: [Errno 256] No more ...

  8. h5新标签介绍

    html5新增了一些标签 这些标签都是语义标签,可以帮助我们更好的理解,代码中的意思:(都是双标签) 案例: 将语义标签翻译过来为 <div class="header"&g ...

  9. MyISAM、InnoDB、Memory这3个常用引擎支持的索引类型

    表格对比了MyISAM.InnoDB.Memory这3个常用引擎支持的索引类型: 索引 MyISAM引擎 InnoDB引擎 Memory引擎 B-Tree索引 支持 支持 支持 HASH索引 不支持 ...

  10. list转datatable,SqlBulkCopy将DataTable中的数据批量插入数据库

    /// <summary> /// 将泛类型集合List类转换成DataTable /// </summary> /// <param name="list&q ...