题目链接  2017 ACM-ICPC Beijing Regional Contest Problem C

题意  给定一个$n$个点$m$条边的无向图。现在有$q$个询问,每次询问格式为$[l, r]$,即图中只有第$l$个点到第$r$个点是安全的,同时

   对于某条边,如果他的两个端点都是安全的,那么这条边也是安全的。

   求在该限制条件下能互相安全到达的点对数。

update:原来这个姿势叫做回滚莫队。

首先要做的就是分块,但是这道题的块的大小很难控制。

从每个点开始按度数分块,保证每个块点的度数和约等于$blocksize$。

然后就是依次处理每个块。假设当前块的左右边界分别为$l$和$r$。

首先对所有边按照左端点(这里默认左端点小于右端点)升序排序。

然后我们取出所有左端点在$[l, r]$内,右端点在$[r + 1, n]$内的询问。对这些询问按照右端点升序排序。

每次处理一个询问的时候,确保那些左右端点都落在$[r + 1, n]$的边已经被添加到并查集(这部分用双指针维护,并且不能撤销)

然后枚举那些左端点落在$[l, r]$的边,如果这条边对于当前询问来说是安全的那么添加到并查集。(这部分并查集的操作是要撤销的)

对于那些左右端点在用一个块内的询问,直接暴力合并然后恢复即可。

按照分块的策略,每个块里面左端点落在$[l, r]$的边的数量大概为$\sqrt{m}$,这样乘上块的个数时间复杂度为$O(m)$

然后还要带上启发式合并的复杂度,所以总的时间复杂度为$O(m^{\frac{3}{2}}logn)$

#include <bits/stdc++.h>

using namespace std;

#define rep(i, a, b)	for (int i(a); i <= (b); ++i)
#define dec(i, a, b) for (int i(a); i >= (b); --i) typedef long long LL; const int N = 1e5 + 10; struct node{
int x, y, id;
void scan(){
scanf("%d%d", &x, &y);
if (x > y) swap(x, y);
} } e[N], q[N], tmp[N]; struct opt{
int x, y, sz, f;
LL ans;
} op[N << 1]; int T;
int cnt, now, tot, n, m, qu, bs, l, r, top, pos;
int belong[N], ed[N], in[N], sz[N], father[N];
vector <node> v[N], g[N];
LL ret[N], ans; bool cmpx(const node &a, const node &b){ return a.x < b.x; }
bool cmpy(const node &a, const node &b){ return a.y < b.y; } int calc(int x){
int l = 1, r = m;
if (e[1].x >= x) return 1;
if (e[m].x < x) return m + 1; while (l + 1 < r){
int mid = (l + r) >> 1;
if (e[mid].x >= x) r = mid;
else l = mid + 1;
} if (e[l].x >= x) return l;
else return r;
} int getfather(int x){ return father[x] == x ? x : getfather(father[x]); } void solve(int x, int y){
int fx = getfather(x), fy = getfather(y);
if (fx == fy) return;
if (sz[fx] < sz[fy]) swap(fx, fy); ++top;
op[top].x = fx;
op[top].y = fy;
op[top].sz = sz[fx];
op[top].f = father[fy];
op[top].ans = ans; father[fy] = fx;
ans += 1ll * sz[fx] * sz[fy];
sz[fx] += sz[fy];
} void undo(){
dec(i, top, 1){
int fx = op[i].x, fy = op[i].y;
father[fy] = op[i].f;
ans = op[i].ans;
sz[fx] = op[i].sz;
}
} int main(){ scanf("%d", &T);
while (T--){
scanf("%d%d%d", &n, &m, &qu);
rep(i, 1, m) e[i].scan();
rep(i, 1, qu) q[i].scan(), q[i].id = i;
sort(e + 1, e + m + 1, cmpx); memset(in, 0, sizeof in);
rep(i, 1, m) ++in[e[i].x]; bs = (int)floor(sqrt((double)(2 * m) * (double)(log(n) / 0.4)));
tot = 0; now = 0;
memset(ed, 0, sizeof ed);
rep(i, 1, n){
now += in[i];
if (now >= bs){
++tot;
belong[i] = tot;
ed[tot] = i;
now = 0;
}
} if (ed[tot] != n){
++tot;
belong[n] = tot;
ed[tot] = n;
} dec(i, n, 1) if (!belong[i]) belong[i] = belong[i + 1]; rep(i, 1, tot){
l = ed[i - 1] + 1, r = ed[i];
v[i].clear();
g[i].clear();
rep(j, 1, m) if (e[j].x >= l && e[j].x <= r) v[i].push_back(e[j]);
rep(j, 1, qu) if (q[j].x >= l && q[j].y <= r) g[i].push_back(q[j]);
} rep(et, 1, tot){
l = ed[et - 1] + 1, r = ed[et]; cnt = 0;
rep(i, 1, qu) if (q[i].x >= l && q[i].x <= r && q[i].y > r){
tmp[++cnt] = q[i];
} sort(tmp + 1, tmp + cnt + 1, cmpy);
sort(e + 1, e + m + 1, cmpx);
pos = calc(r + 1);
sort(e + pos, e + m + 1, cmpy); rep(i, 1, n) father[i] = i, sz[i] = 1;
ans = 0;
for (int j = pos, k = 1; k <= cnt; ++k){
while (e[j].y <= tmp[k].y && j <= m){
solve(e[j].x, e[j].y);
++j;
} top = 0;
for (auto edge : v[et]){
if (tmp[k].x <= edge.x && edge.y <= tmp[k].y){
solve(edge.x, edge.y);
}
} ret[tmp[k].id] = ans;
undo();
} rep(i, 1, n) father[i] = i, sz[i] = 1;
ans = 0; for (auto query : g[et]){
top = 0;
for (auto edge : v[et]){
if (query.x <= edge.x && edge.y <= query.y){
solve(edge.x, edge.y);
}
}
ret[query.id] = ans;
undo();
} }
rep(i, 1, qu) printf("%lld\n", ret[i]);
} return 0;
}

  

HihoCoder 1629 Graph (2017 ACM-ICPC 北京区域赛 C题,回滚莫队 + 启发式合并 + 可撤销并查集)的更多相关文章

  1. 2015 ACM / ICPC 亚洲区域赛总结(长春站&北京站)

    队名:Unlimited Code Works(无尽编码)  队员:Wu.Wang.Zhou 先说一下队伍:Wu是大三学长:Wang高中noip省一:我最渣,去年来大学开始学的a+b,参加今年区域赛之 ...

  2. 2017 ACM/ICPC(北京)总结

    这个季节的,北京真的很冷. 下午的热身赛,我依然先去敲一道搜索题,但是很不幸这道搜索题坑点还是蛮多的,浪费了好长时间后依然没能A掉,期间Codeblocks崩溃一次使得代码完全丢失,在队友的建议下便暂 ...

  3. Hihocoder 1634 Puzzle Game(2017 ACM-ICPC 北京区域赛 H题,枚举 + 最大子矩阵变形)

    题目链接  2017 Beijing Problem H 题意  给定一个$n * m$的矩阵,现在可以把矩阵中的任意一个数换成$p$,求替换之后最大子矩阵的最小值. 首先想一想暴力的方法,枚举矩阵中 ...

  4. hihoCoder #1871 : Heshen's Account Book-字符串暴力模拟 自闭(getline()函数) (ACM-ICPC Asia Beijing Regional Contest 2018 Reproduction B) 2018 ICPC 北京区域赛现场赛B

    P2 : Heshen's Account Book Time Limit:1000ms Case Time Limit:1000ms Memory Limit:512MB Description H ...

  5. hihoCoder #1870 : Jin Yong’s Wukong Ranking List-闭包传递(递归) (ACM-ICPC Asia Beijing Regional Contest 2018 Reproduction A) 2018 ICPC 北京区域赛现场赛A

    P1 : Jin Yong’s Wukong Ranking List Time Limit:1000ms Case Time Limit:1000ms Memory Limit:512MB Desc ...

  6. 2016 年 ACM/ICPC 青岛区域赛 Problem C Pocky

    昨晚乱入学弟的训练赛,想了一下这个题.推导的过程中,加深了对公理化的概率论理解.$\newcommand{\d}{\mathop{}\!\mathrm{d}}$ 解法一 考虑 $ d < L$ ...

  7. Known Notation括号匹配类问题(2014年ACM/ICPC 亚洲区域赛牡丹江)

    题意: 给你数字或 * 的串,你可以交换一个*和数字.在最前面添1.在一个地方插入*,问你使串满足入栈出栈的(RNP)运算法则. 思路: 引用:https://blog.csdn.net/u01158 ...

  8. Heshen's Account Book HihoCoder - 1871 2018北京区域赛B题(字符串处理)

    Heshen was an official of the Qing dynasty. He made a fortune which could be comparable to a whole c ...

  9. Digit sum (第 44 届 ACM/ICPC 亚洲区域赛(上海)网络赛)进制预处理水题

    131072K   A digit sum S_b(n)Sb​(n) is a sum of the base-bb digits of nn. Such as S_{10}(233) = 2 + 3 ...

随机推荐

  1. Oracle 遇到的问题:IMP-00041: 警告: 创建的对象带有编译警告解决办法

    出现IMP-00041: 警告: 创建的对象带有编译警告:以后再做数据迁移的时候需要额外注意,尤其用户中有视图或者触发器对象的时候.用户的环境是这样的,在库里有三个oracle的用户,其中一个用户中有 ...

  2. ironic baremetal node rescue/unrescue mode

    环境ironic-api ironic-conductor,ironicclient均升级为Queens版本 官网说明API版本为1.38才支持rescue/unrescue,所以修改下openrc文 ...

  3. Mysql DISTINCT问题

    问题描述 因为要设计一个数据库表,进行一个倒序去重的操作. 例如: id Name 1 B 2 A 3 A 4 C 5 C 6 B 场景:例如说我们需要得到一个用户的搜索记录,那么肯定不会仅仅根据时间 ...

  4. VMware下Linux配置局域网和外网访问

    我想尝试的是利用本机的ip+port来访问虚拟机上的web服务器,因为这样的话,我就能够将我的web服务器部署成为一个能让外网访问的服务器了,首先说下我的环境: 主机:系统win7,ip地址172.1 ...

  5. 解决:spring security 登录页停留时间过长 跳转至 403页面

    前言:最近的项目中用到了spring security组件,说句显low的话:我刚开始都不知道用了security好不勒,提了bug,在改的过程中,遇到了一些问题,找同事交流,才知道是用的securi ...

  6. PHP异常处理类(文件上传提示)

    知识点: 大部分时候我们的代码总有各种各样的bug,新手程序员(比如我)最经常的工作就是不停的报错和echo变量,一个好的异常处理类可以帮我们更快+更容易理解报错代码的问题,同时,异常处理还可以避免一 ...

  7. springmvc中RedirectAttributes、SessionFlashMapManager的作用

    RedirectAttributes 在重定向的时候可以传参,不能跨站传参,因为参数是保存在服务器端Session中SessionFlashMapManager 是RedirectAttributes ...

  8. 基于HTTP协议的轻量级开源简单队列服务:HTTPSQS[转]

    HTTPSQS(HTTP Simple Queue Service)是一款基于 HTTP GET/POST 协议的轻量级开源简单消息队列服务,使用 Tokyo Cabinet 的 B+Tree Key ...

  9. [CF1045C]Hyperspace Highways

    题目大意:给一张$n$个点$m$条边的图,保证若有一个环,一定是完全子图,多次询问两个点之间的最短路径长度 题解:把完全子图缩成一个点,圆方树,方点权值设成$1$,圆点设成$0$即可. 卡点:数组开小 ...

  10. POJ 3974 Palindrome | 马拉车模板

    给一个字符串,求最长回文字串有多长 #include<cstdio> #include<algorithm> #include<cstring> #define N ...