P5443 [APIO2019]桥梁 [分块+并查集]
分块+并查集,大板子,没了。
并查集不路径压缩,可撤销,然后暴力删除
这样对于每个块都是独立的,所以直接搞就行了。
然后块内修改操作搞掉,就是单独的了
// powered by c++11
// by Isaunoya
#include <bits/stdc++.h>
#define rep(i, x, y) for (register int i = (x); i <= (y); ++i)
#define Rep(i, x, y) for (register int i = (x); i >= (y); --i)
using namespace std;
using db = double;
using ll = long long;
using uint = unsigned int;
// #define int long long
using pii = pair<int, int>;
#define ve vector
#define Tp template
#define all(v) v.begin(), v.end()
#define sz(v) ((int)v.size())
#define pb emplace_back
#define fir first
#define sec second
// the cmin && cmax
Tp<class T> void cmax(T& x, const T& y) {
if (x < y) x = y;
}
Tp<class T> void cmin(T& x, const T& y) {
if (x > y) x = y;
}
// sort , unique , reverse
Tp<class T> void sort(ve<T>& v) { sort(all(v)); }
Tp<class T> void unique(ve<T>& v) {
sort(all(v));
v.erase(unique(all(v)), v.end());
}
Tp<class T> void reverse(ve<T>& v) { reverse(all(v)); }
const int SZ = 0x191981;
struct FILEIN {
~FILEIN() {}
char qwq[SZ], *S = qwq, *T = qwq, ch;
char GETC() { return (S == T) && (T = (S = qwq) + fread(qwq, 1, SZ, stdin), S == T) ? EOF : *S++; }
FILEIN& operator>>(char& c) {
while (isspace(c = GETC()))
;
return *this;
}
FILEIN& operator>>(string& s) {
while (isspace(ch = GETC()))
;
s = ch;
while (!isspace(ch = GETC())) s += ch;
return *this;
}
Tp<class T> void read(T& x) {
bool sign = 1;
while ((ch = GETC()) < 0x30)
if (ch == 0x2d) sign = 0;
x = (ch ^ 0x30);
while ((ch = GETC()) > 0x2f) x = x * 0xa + (ch ^ 0x30);
x = sign ? x : -x;
}
FILEIN& operator>>(int& x) { return read(x), *this; }
// FILEIN& operator>>(signed& x) { return read(x), *this; }
FILEIN& operator>>(unsigned& x) { return read(x), *this; }
} in;
struct FILEOUT {
const static int LIMIT = 0x114514;
char quq[SZ], ST[0x114];
signed sz, O;
~FILEOUT() { flush(); }
void flush() {
fwrite(quq, 1, O, stdout);
fflush(stdout);
O = 0;
}
FILEOUT& operator<<(char c) { return quq[O++] = c, *this; }
FILEOUT& operator<<(string str) {
if (O > LIMIT) flush();
for (char c : str) quq[O++] = c;
return *this;
}
Tp<class T> void write(T x) {
if (O > LIMIT) flush();
if (x < 0) {
quq[O++] = 0x2d;
x = -x;
}
do {
ST[++sz] = x % 0xa ^ 0x30;
x /= 0xa;
} while (x);
while (sz) quq[O++] = ST[sz--];
return;
}
FILEOUT& operator<<(int x) { return write(x), *this; }
// FILEOUT& operator<<(signed x) { return write(x), *this; }
FILEOUT& operator<<(unsigned x) { return write(x), *this; }
} out;
const int maxn = 2e5 + 52;
int n, m, num = 0;
int q, len, ans[maxn];
bool vis[maxn], used[maxn];
vector<int> b;
struct Edge {
int u, v, w;
} e[maxn];
struct Que {
int op, x, y;
} Q[maxn];
struct Qry {
int id, u, v, w;
bool operator<(const Qry& other) const {
if (w != other.w) return w > other.w;
return id < other.id;
}
};
vector<Qry> qr;
struct DSU {
int n, fa[maxn], sz[maxn], top, sta[maxn], stb[maxn];
inline void reset(int _n) {
n = _n, top = 0;
for (int i = 1; i <= n; i++) sz[fa[i] = i] = 1;
}
inline void reset() {
while (top) {
int u = sta[top], v = stb[top];
sz[u] -= sz[v], fa[v] = v;
top--;
}
}
inline int find(int x) { return x == fa[x] ? x : find(fa[x]); }
inline int getsize(int x) {
int fx = find(x);
return sz[fx];
}
inline void merge(int u, int v, int r) {
if ((u = find(u)) == (v = find(v))) return;
if (sz[u] < sz[v]) u ^= v ^= u ^= v;
sz[u] += sz[v], fa[v] = u;
if (r) sta[++top] = u, stb[top] = v;
}
} dsu;
inline void solve(int l, int r) {
dsu.reset(n);
b.clear(), qr.clear();
for (int i = 1; i <= m; i++) {
used[i] = 0;
}
for (int i = l; i <= r; i++) {
if (Q[i].op == 1) {
used[Q[i].x] = 1;
} else {
qr.push_back({ ++q, Q[i].x, i, Q[i].y });
}
}
for (int i = 1; i <= m; i++)
if (!used[i])
qr.push_back({ -1, e[i].u, e[i].v, e[i].w });
else
b.push_back(i);
sort(qr.begin(), qr.end());
for (auto x : qr) {
if (x.id == -1) {
dsu.merge(x.u, x.v, 0);
continue;
}
for (int i = x.v; i >= l; i--) {
if (Q[i].op == 1) {
if (!vis[Q[i].x]) {
vis[Q[i].x] = 1;
if (Q[i].y >= x.w) {
dsu.merge(e[Q[i].x].u, e[Q[i].x].v, 1);
}
}
}
}
for (auto y : b) {
if (!vis[y] && e[y].w >= x.w) {
dsu.merge(e[y].u, e[y].v, 1);
}
}
ans[x.id] = dsu.getsize(x.u);
for (auto y : b) {
vis[y] = 0;
}
dsu.reset();
}
for (int i = l; i <= r; i++) {
if (Q[i].op == 1) {
e[Q[i].x].w = Q[i].y;
}
}
}
signed main() {
#ifdef _WIN64
freopen("testdata.in", "r", stdin);
#else
ios_base ::sync_with_stdio(false);
cin.tie(nullptr), cout.tie(nullptr);
#endif
// code begin.
in >> n >> m;
for (int i = 1; i <= m; i++) {
int u, v, w;
in >> u >> v >> w;
e[i] = { u, v, w };
}
in >> num;
len = 900;
for (int i = 1; i <= num; i++) {
in >> Q[i].op >> Q[i].x >> Q[i].y;
}
for (int i = 1; i <= num; i += len) solve(i, min(num, i + len - 1));
for (int i = 1; i <= q; i++) out << ans[i] << '\n';
return 0;
// code end.
}
P5443 [APIO2019]桥梁 [分块+并查集]的更多相关文章
- [APIO2019] [LOJ 3145] 桥梁(分块+并查集)(有详细注释)
[APIO2019] [LOJ 3145] 桥梁(分块+并查集)(有详细注释) 题面 略 分析 考试的时候就感觉子任务4是突破口,结果却写了个Kruskal重构树,然后一直想怎么在线用数据结构维护 实 ...
- 洛谷P3247 最小公倍数 [HNOI2016] 分块+并查集
正解:分块+并查集 解题报告: 传送门! 真的好神仙昂QAQ,,,完全想不出来,,,还是太菜了QAQ 首先还是要说下,这题可以用K-D Tree乱搞过去(数据结构是个好东西昂,,,要多学学QAQ),但 ...
- [BZOJ4537][HNOI2016]最小公倍数(分块+并查集)
4537: [Hnoi2016]最小公倍数 Time Limit: 40 Sec Memory Limit: 512 MBSubmit: 1687 Solved: 607[Submit][Stat ...
- BZOJ4320 ShangHai2006 Homework(分块+并查集)
考虑根号分块.对于<√3e5的模数,每加入一个数就暴力更新最小值:对于>√3e5的模数,由于最多被分成√3e5块,查询时对每一块找最小值,这用一些正常的DS显然可以做到log,但不太跑得过 ...
- HDU 6271 Master of Connected Component(2017 CCPC 杭州 H题,树分块 + 并查集的撤销)
题目链接 2017 CCPC Hangzhou Problem H 思路:对树进行分块.把第一棵树分成$\sqrt{n}$块,第二棵树也分成$\sqrt{n}$块. 分块的时候满足每个块是一个 ...
- bzoj 4537: [Hnoi2016]最小公倍数 分块+并查集
题目大意: 给定一张n个点m条边的无向图,每条边有两种权.每次询问某两个点之间是否存在一条路径上的边的两种权的最大值分别等于给定值. n,q <= 50000. m <= 100000 题 ...
- P5443 [APIO2019]桥梁
传送门 子任务 $4$ 告诉我们可以离线搞带权并查集 从大到小枚举询问,从大到小连边 如果没有修改操作就可以过了 但是有修改,考虑最暴力的暴力,搞可撤销并查集 同样先离线,从大到小处理询问时,按原边权 ...
- Codeforces 506D Mr. Kitayuta's Colorful Graph(分块 + 并查集)
题目链接 Mr. Kitayuta's Colorful Graph 把每种颜色分开来考虑. 所有的颜色分为两种:涉及的点的个数 $> \sqrt{n}$ 涉及的点的个数 $<= ...
- 洛谷P4004 Hello world!(分块+并查集)
传送门 虽然洛谷数据水,然而咱最终还是没有卡过uoj上的毒瘤数据-- 神tm全uoj就3个人过了这题-- 首先,每个数最多被开根\(6\)次,开到\(1\)之后就别管它了,把它用并查集连到它父亲上 它 ...
随机推荐
- 机器学习-NLP之Word embedding 原理及应用
概述 自然语言是非常复杂多变的,计算机也不认识咱们的语言,那么咱们如何让咱们的计算机学习咱们的语言呢?首先肯定得对咱们的所有文字进行编码吧,那咱们很多小伙伴肯定立马就想出了这还不简单嘛,咱们的计算机不 ...
- hive安装启动错误总结
错误一: Exception in thread "main" java.lang.NoClassDefFoundError: jline/console/completer/Ar ...
- Linux系统的用户和用户组管理
一.用户账户管理 Linux/Unix是一个用户.多任务的操作系统:在讲Linux账号及账户组管理之前,先简单了解一下多用户.多任务操作系统的基本概念. Linux的单用户多任务 在Linux下,当你 ...
- OpenCV3入门(八)图像边缘检测
1.边缘检测基础 图像的边缘是图像的基本特征,边缘点是灰度阶跃变化的像素点,即灰度值的导数较大或极大的地方,边缘检测是图像识别的第一步.用图像的一阶微分和二阶微分来增强图像的灰度跳变,而边缘也就是灰度 ...
- Git 分支设计规范
概述 这篇文章分享 Git 分支设计规范,目的是提供给研发人员做参考. 规范是死的,人是活的,希望自己定的规范,不要被打脸. 在说 Git 分支规范之前,先说下在系统开发过程中常用的环境. 简称 全称 ...
- c#设计模式读书博客
第一次在博客园撸博客,也是为了鞭策自己去学习进步,过年之后买了一本<C#设计模式>这是我一直很想去学习的一本书.然后用博客记录我的学习历程,并且分享给需要的人.这本书记录的设计模式有23种 ...
- postman简单接口测试
Postman简单接口测试 1. get请求: a. 选择get请求时,地址栏输入地址,如果需要添加参数,可以直接在地址栏加?后面写参数,也可以在点击params添加参数 b. 在headers中添加 ...
- kubeadm安装Kubernetes 1.14最佳实践
前言 Kubernetes作为容器编排工具,简化容器管理,提升工作效率而颇受青睐.很多新手部署Kubernetes由于“上网”问题举步维艰,本文以实战经验详解kubeadm不用“翻墙”部署Kubern ...
- [ERROR]pip insall pyodbc
- 错误代码如下: pip install pyodbc Looking in indexes: http://172.16.1.250/repository/douban/simple Collec ...
- vue中阻止事件穿透的方法
默认情况下,事件在h5页面会穿透传递,比如一div里面套一个div,点击上层div,下层div也会响应 要阻止事件穿透,使用event.stopPropagation(); 代码示例: <div ...